JavaRush /Курсы /Swift SELF /Строки в Swift: String, интерполяция "\(...)"

Строки в Swift: String, интерполяция "\(...)"

Swift SELF
2 уровень , 2 лекция
Открыта

1. Основы строк в Swift

Если числа — это то, чем программа думает, то строки — это то, чем программа разговаривает с человеком. Почти любая консольная задача в итоге сводится к тому, что вы должны вывести результат в правильном формате: словами, с пробелами, иногда со знаками : или =. И даже если задача чисто математическая, вы всё равно печатаете текст.

В Swift строковый тип называется String. Он хранит последовательность символов, то есть «текст». Важный момент: строка — это данные, такие же, как число. Её можно сохранить в переменную, передать дальше по коду, «собрать» из кусочков, а потом вывести.

Самая простая строка — это строковый литерал, то есть текст в кавычках:

let title = "LibraryCLI"
print(title) // LibraryCLI

Здесь title — константа типа String. Никакой магии: просто значение, которое хранит текст.

Литералы строк: "..." и что считается символом

Когда вы видите "Hello", мозг разработчика часто думает: «ну это же просто слово». Но для программы это набор символов. И программа не умеет угадывать «правильные пробелы» или «где поставить запятую», пока вы сами это не напишете. Пробел — это тоже символ. Точка — тоже символ. Даже два пробела подряд — это два символа (и иногда это может сломать проверку ответа в задачах).

В простых задачах уровня 2 нам достаточно запомнить несколько практических правил. Строка пишется в двойных кавычках, внутри можно хранить любые обычные символы, и если вы хотите вывести красивую фразу, вы должны явно добавить пробелы и знаки препинания туда, где они нужны.

Например, сравним «красиво» и «слеплено»:

let firstName = "Ivan"
let lastName = "Petrov"

let good = firstName + " " + lastName
print(good) // Ivan Petrov

let bad = firstName + lastName
print(bad)  // IvanPetrov

Обратите внимание: " " — это строка из одного пробела. Да, пробел — настолько важен, что у него есть собственная строка.

Конкатенация через +: склеиваем строки как LEGO

Слово «конкатенация» звучит так, будто это заклинание из мира компиляторов, но по факту это «склеивание строк». В Swift строки можно складывать оператором +. Результатом будет новая строка.

Тут удобно думать про строки как про LEGO‑кирпичики: у вас есть кусочки текста, и вы собираете из них одну фразу. Но, как и в LEGO, если вы забыли деталь (например пробел), конструкция получается странной.

Пример: делаем аккуратное сообщение о количестве книг. Пока без ввода — просто как тренировка форматирования.

let libraryName = "City Library"
let booksCount = 12

let message = "Library: " + libraryName + ", books: " + "\(booksCount)"
print(message) // Library: City Library, books: 12

Стоп. А что это за "\(booksCount)"? Это уже интерполяция, чуть ниже мы разберём её. Пока заметим важное: оператор + умеет склеивать строку со строкой, но не «строку с числом».

Почему "x=" + 10 не компилируется

Очень типичная ситуация новичка: вы хотите вывести «x=10», пишете "x=" + 10, и Swift говорит: «нет». Причина простая и даже полезная: + — это не «универсальный скотч», а оператор, который должен понимать, что именно он складывает.

Строка — это String. Число — это Int. И компилятор не хочет угадывать, как именно вы хотите превратить число в текст. Поэтому выражение вида str + 1 для Swift выглядит подозрительно, и компилятор выдаёт ошибку, потому что типы не совпадают. Такая ситуация даже приводится как пример того, как компилятор ищет проблему в выражении str + 1 и почему человеку сразу понятно, что не так, а компилятору нужно вывести это через систему ограничений типов.

Практически это означает одно: нельзя складывать String и Int напрямую. Нужно либо явно превратить число в строку (позже мы научимся делать это через ввод и преобразования), либо использовать интерполяцию строк.

Чтобы не ломать компиляцию, «плохую» строку можно оставить как комментарий — чтобы помнить, что так делать нельзя:

let x = 10
let prefix = "x="

// let text = prefix + x   // так нельзя: String + Int
let okText = prefix + "\(x)"
print(okText) // x=10

Сейчас это выглядит как «костыль». Но это на самом деле подсказка к следующему разделу: интерполяция — наш основной инструмент для таких задач.

Интерполяция "\(...)": самый дружелюбный способ вставлять значения

Интерполяция строк в Swift — это когда вы внутри строки пишете \(что-то) и Swift аккуратно вставляет туда значение, превращая его в текст. Для новичка это обычно самое приятное: меньше ручного склеивания, меньше забытых пробелов, и код читается как нормальная фраза.

Выглядит это так:

let bookTitle = "Dune"
let pages = 412

let text = "Book: \(bookTitle), pages: \(pages)"
print(text) // Book: Dune, pages: 412

Обратите внимание на ощущение «это читается как предложение». Именно это качество делает интерполяцию предпочтительным способом форматирования в большинстве задач.

Ещё важный плюс: в интерполяцию можно вставлять не только Int, но и вообще любые значения, которые нормально печатаются. А печататься они у нас уже умеют, потому что print(...) — наш базовый инструмент.

Интерполяция выражений: \(a + b) и «мини‑формулы» в тексте

Когда вы впервые видите "\(a + b)", может показаться, что Swift начинает «выполнять код внутри строки». Так и есть: внутри \(…) можно писать выражение, и оно будет вычислено, а результат подставится в строку.

Это суперполезно для задач, где нужно вывести не только число, но и пояснение: «3 + 4 = 7». С конкатенацией это делается длинно и легко ошибиться. С интерполяцией — аккуратно.

let a = 3
let b = 4

let line = "\(a) + \(b) = \(a + b)"
print(line) // 3 + 4 = 7

Заметьте, как хорошо видно структуру результата. Такой код легко проверить глазами, а это в программировании почти суперспособность.

И да: это тот самый момент, когда можно легально «вставить математику в текст» и почувствовать себя немного волешбником, но без перебора.

Небольшой рефакторинг: читаемость важнее «одной строки»

На первых порах очень хочется написать всё «в одну строку», потому что кажется, что так «профессиональнее». На практике профессионально — это когда через неделю вы сами понимаете свой код без археологической экспедиции.

Поэтому полезное правило: если строка собирается из нескольких частей, особенно если там есть числа и выражения, не бойтесь делать промежуточные let. Это не «лишний код», это забота о тех, кто будет читать этот код.

Сравним. Вариант «слишком плотно»:

let currentPage = 37
let totalPages = 120
print("Progress: \(currentPage)/\(totalPages) (\(currentPage * 100 / totalPages)%)")

Вариант красивее:

let currentPage = 37
let totalPages = 120

let percent = currentPage * 100 / totalPages // Int-деление, дробь отбрасывается
let text = "Progress: \(currentPage)/\(totalPages) (\(percent)%)"
print(text) // Progress: 37/120 (30%)

Во втором варианте проще понять, где что считается, и проще исправить, если вы вдруг изменили формулу. И да, обратите внимание на «целочисленность»: percent получился Int, потому что мы работаем с Int.

2. Мини‑приложение: печатаем статус «мини‑библиотеки»

Чтобы примеры не были набором разрозненных строк, давайте продолжим развивать маленькое консольное приложение‑заготовку. Пусть это будет «мини‑библиотека» (очень ранний предок нашего будущего CLI‑проекта): программа пока не читает ввод и не хранит данные, она просто красиво печатает статус — название библиотеки, текущую книгу и прогресс чтения.

Наша цель здесь не «сделать полезное приложение», а натренировать навык: превращать числа и данные в аккуратный текстовый вывод, не теряя пробелы и смысл.

Начнём с основы: зададим данные и выведем аккуратную шапку.

let appName = "MiniLibrary"
let version = 1

let header = "\(appName) v\(version)"
print(header) // MiniLibrary v1

Обратите внимание: v\(version) — это типичный паттерн, и он читается отлично.

Теперь добавим «данные о книге» и соберём одну красивую строку отчёта. Нам понадобятся и String, и Int.

let bookTitle = "Clean Code"
let currentPage = 57
let totalPages = 464

let progress = "\(currentPage)/\(totalPages)"
print("Now reading: \(bookTitle) — \(progress)") // Now reading: Clean Code — 57/464

Символ (длинное тире) — это тоже просто символ строки. Swift не возражает, если вы печатаете нормальный человеческий текст.

Добавим процент, используя арифметику Int из прошлой лекции:

let currentPage = 57
let totalPages = 464

let percent = currentPage * 100 / totalPages
let line = "Progress: \(percent)%"
print(line) // Progress: 12%

И теперь соберём «итоговый отчёт» в более читаемом стиле: отдельные кусочки в let, потом финальная строка.

let libraryName = "City Library"
let bookTitle = "Clean Code"
let currentPage = 57
let totalPages = 464

let percent = currentPage * 100 / totalPages
let report = "Library: \(libraryName). Book: \(bookTitle). \(percent)% read."
print(report) // Library: City Library. Book: Clean Code. 12% read.

Пока выглядит скромно, но это именно тот навык, который потом спасает на реальных задачах: вы делаете вывод предсказуемым, понятным и «как в условии».

Схема: как мы собираем текст

Иногда полезно увидеть процесс как мини‑конвейер:

flowchart LR
    A["Данные (Int/String)"] --> B["Формулы (Int)"]
    B --> C["Интерполяция в String"]
    C --> D["print(...)"]

В этой лекции мы в основном тренируем узел C: превращение данных в текст.

3. Типичные ошибки при работе со строками

Ошибка №1: забытые пробелы при конкатенации.
Когда вы склеиваете строки через +, легко получить "IvanPetrov" вместо "Ivan Petrov". Проблема не в Swift, а в том, что пробел — такой же символ, как буква. Хороший способ лечения — чаще использовать интерполяцию, а если всё же склеиваете, явно добавлять " " там, где по смыслу должен быть пробел.

Ошибка №2: попытка сложить строку и число оператором +.
Выражение вида "x=" + 10 не компилируется, потому что + не умеет автоматически приводить Int к String. С точки зрения системы типов это действительно разные миры, и пример str + 1 — классическая ситуация, где компилятор честно говорит «тип не тот». Лучшее решение на этом этапе — интерполяция: "x="\(10).

Ошибка №3: превращение вывода в «лапшу» из + + +.
Иногда новичок начинает собирать строку так: "a=" + "\(a)" + ", b=" + "\(b)" + ... — и через минуту уже никто не понимает, сколько там кавычек и где потерялась запятая. Интерполяция заметно чище: "a="\(a), b=\(b). Если строка всё равно получается длинной, разбивайте её на промежуточные let.

Ошибка №4: ожидание, что программа «догадается» о пунктуации.
Частая мелочь: забыли двоеточие, точку, запятую или пробел в конце, и ответ не засчитывается. Для человека это «ну понятно же», а для проверяющей системы это совсем другой текст. Относитесь к строкам как к точному контракту: что вывели — то и считается.

Ошибка №5: слишком раннее усложнение и попытка «умничать про строки».
Swift действительно относится к строкам серьёзно, потому что текст бывает сложнее, чем кажется (юникод, составные символы и так далее), и в документах подчёркивается, что строка в Swift ориентирована на человеческое восприятие символов. Но на нашем уровне это не повод паниковать: сегодня достаточно уверенно владеть кавычками, + и "\(...)", а всё остальное придёт позже, когда будет реальная потребность.

1
Задача
Swift SELF, 2 уровень, 2 лекция
Недоступна
Бейдж посетителя
Бейдж посетителя
1
Задача
Swift SELF, 2 уровень, 2 лекция
Недоступна
Шапка релиза
Шапка релиза
1
Задача
Swift SELF, 2 уровень, 2 лекция
Недоступна
Школьные формулы
Школьные формулы
1
Задача
Swift SELF, 2 уровень, 2 лекция
Недоступна
Прогресс чтения
Прогресс чтения
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ