Перейти к содержимому
Теория · Строки и символы · урок 1 из 7

Строки

Чему вы научитесь

Чему вы научитесь:

  • считать символы строки, проверять её на пустоту и склеивать строки;
  • объяснять, почему у строки "café" значения count и utf8.count различаются;
  • доставать символы строки без s[0]: через first, prefix и индекс строки;
  • переводить строку в заглавные и строчные буквы, искать в ней текст, разбивать её на части и склеивать обратно.
Нитка из четырёх больших бусин-символов и пяти маленьких бусин-байтов: под последним символом их две

Представьте нитку с бусинами. Каждая крупная бусина — один символ: буква, цифра, пробел или знак препинания. Строка "café" — нитка из четырёх крупных бусин: c, a, f и é.

Если присмотреться, под каждой крупной бусиной висят мелкие. Это байты — маленькие числа, которыми компьютер записывает символ в память. Под c, a и f висит по одной мелкой бусине, а под é — две.

В этом уроке мы работаем только с крупными бусинами: считаем их, нанизываем новые и сравниваем две нитки. Мелкие бусины пока не понадобятся.

Зачем считать символы? Приложение не пускает дальше с пустым полем имени, а ник в игре бывает не длиннее 12 символов. Чтобы проверить такие правила, нужно знать, сколько символов в строке и есть ли они вообще:

SWIFT
let name = "Anna"
let empty = ""
print(name.count, name.isEmpty) // 4 false
print(empty.count, empty.isEmpty) // 0 true

Давайте разберём программу по строкам:

  1. let name = "Anna" — нитка из четырёх бусин.
  2. let empty = "" — нитка без единой бусины. Две кавычки подряд записывают пустую строку.
  3. name.count даёт число символов, 4, а name.isEmpty отвечает, пуста ли строка: false.
  4. У пустой строки count равен 0, а isEmpty даёт true.

Сколько символов в строке

Запись через точку спрашивает у строки то, что она знает о себе. name.count читается как «число символов в name».

count — число символов

count считает крупные бусины, то есть символы. Пробел и знак препинания — тоже символы: в строке "Hi, Anna" их восемь.

isEmpty — пуста ли строка

isEmpty даёт true, когда в строке нет ни одного символа. Строка из одного пробела " " не пустая: в ней один символ, и isEmpty даёт false.

Пустоту можно проверить и сравнением name.count == 0. Но в Swift принято писать isEmpty: эта запись короче и читается как вопрос «пуста ли строка?».

Склеивание строк

Две строки склеивают оператором +, а оператор += дописывает строку в конец переменной:

SWIFT
var greeting = "Hello"
greeting += ", " + name
print(greeting) // Hello, Anna
print(greeting.count) // 11

Разберём по строкам:

  1. var greeting = "Hello" — переменная: к этой нитке можно добавлять бусины.
  2. ", " + name склеивает две строки в новую: ", Anna".
  3. += дописывает её в конец greeting. Это то же самое, что greeting = greeting + ", " + name.
  4. print печатает Hello, Anna, а count даёт 11: запятая и пробел тоже считаются.

Здесь картинка с бусинами неточна. Настоящую бусину нельзя нанизать сразу на две нитки. А + копирует символы: после склеивания в name по-прежнему лежит "Anna".

Сравнение строк

Строки сравнивают операторами == и <. == проверяет, что две строки совпадают символ в символ.

Как вы уже знаете, < сравнивает строки по символам слева направо, почти как слова в словаре: "apple" < "banana" даёт true. Но в этом словаре все заглавные латинские буквы стоят раньше строчных, поэтому "Zoo" < "apple" тоже даёт true.

Пробел — такой же символ, как буква. Поэтому "Anna " == "Anna" даёт false: в первой строке пять символов, а во второй четыре. Из-за лишнего пробела в конце введённого имени два имени, одинаковых на вид, часто не совпадают.

Кавычки и переносы внутри строки

Кавычка заканчивает строку, а перенос строки внутри обычных кавычек писать нельзя. Как тогда записать текст с кавычками или текст из нескольких строк? Для этого есть три записи:

SWIFT
print("Say \"hi\"") // Say "hi"
print("one\ntwo") // one
                  // two
let poem = """
    Roses are red,
    "Swift" is new.
    """
print(poem) // Roses are red,
            // "Swift" is new.

\" — кавычка внутри строки

Обратная косая черта перед кавычкой говорит Swift: это не конец строки, а сам знак кавычки. Так же \\ записывает саму обратную косую черту.

\n — перевод строки

\n — один невидимый символ, перевод строки. Там, где он стоит, print переходит на новую строку, поэтому "one\ntwo" печатается в две строки. Когда вывод занимает несколько строк, в примерах он записан в комментариях друг под другом. count считает \n одним символом: в "one\ntwo" их семь.

""" — многострочная строка

Многострочная строка начинается и заканчивается тремя кавычками, каждая тройка на своей строке. Всё, что между этими строками, попадает в текст как есть: переносы строк и кавычки без обратной косой черты. Перенос сразу после открывающих """ и перенос перед закрывающими в текст не попадают: poem начинается с Roses и кончается точкой.

Отступ перед закрывающими """ Swift убирает из каждой строки текста. Поэтому многострочную строку можно выровнять вместе с остальным кодом, и лишние пробелы в текст не попадут.

Частая ошибка

Строку объявили через let, а потом попробовали её дописать:

SWIFT
let title = "Swift"
title += " 6" // ✗
TEXT
error: left side of mutating operator isn't mutable: 'title' is a 'let' constant

Программа не компилируется: += меняет саму строку, а title — константа. Если строку нужно дописывать, объявите её через var. Если нужна новая строка, соберите её в другую константу: let fullTitle = title + " 6".

Главное

  • count — число символов строки, isEmpty — проверка, что строка пустая; у "" count равен 0.
  • + склеивает две строки в новую, а += дописывает строку в конец переменной var.
  • Пробел, запятая и перевод строки \n — такие же символы, как буквы, и count их считает.
  • \" записывает кавычку внутри строки, а """ начинает многострочную строку.