Métodos de String — Guia Completo em Swift: Um Guia Detalhado
Что это такое и зачем? (аналогия из реальной жизни)
Представь, что ты — библиотекарь. У тебя есть огромное количество книг (строк). Каждая книга — это просто набор букв, но ты можешь с ней делать разные полезные вещи:
- Найти, есть ли в книге слово "приключения"
- Заменить старое название на новое
- Разрезать книгу на главы
- Посчитать, сколько букв "а" в тексте
- Сделать все буквы заглавными для обложки
В программировании строки — это тот же текст. А методы строк — это готовые инструменты (как ножницы, лупа или клей), которые Swift даёт тебе в руки, чтобы ты мог управлять текстом, не изобретая велосипед.
💡 Важно: Строка в Swift — это не просто набор символов. Это сложная структура, которая умеет делать много полезного сама, без твоей помощи. Твоя задача — только попросить её об этом.
Теория: как это работает изнутри
Давай заглянем под капот. Когда ты пишешь "Привет, мир!", Swift создаёт в памяти специальный объект — String. Этот объект хранит не просто буквы, а целую коллекцию символов (Character).
Каждый символ может быть:
- Буквой (A, б, Я)
- Цифрой (1, 2, 3)
- Знаком препинания (., !, ?)
- Эмодзи (😀, 🚀)
- Пробелом
Но самое интересное — Swift хранит строку особым образом. Он использует Unicode — международный стандарт, который позволяет хранить текст на любом языке мира: русском, китайском, арабском. Поэтому одна и та же буква "ё" может быть записана двумя способами: как один символ или как буква "е" + две точки. Swift это учитывает!
Методы строк — это встроенные функции, которые прикреплены к каждой строке. Ты вызываешь их через точку:
// Общий синтаксис:
// строка.имяМетода(параметры)
let имя = "Анна"
// Вызываем метод, который делает первую букву заглавной
let результат = имя.uppercased()
print(результат) // "АННА"
⚠️ Запомни: Большинство методов строк не изменяют исходную строку, а возвращают новую. Оригинал остаётся нетронутым. Это называется иммутабельность (неизменяемость).
Синтаксис в Swift: все формы и варианты
Давай разберём все основные методы строк. Я разделил их на группы, чтобы было легче запомнить.
1. Изменение регистра
| Метод | Что делает | Пример | Результат |
|---|---|---|---|
uppercased() | Все буквы заглавные | "hello".uppercased() | "HELLO" |
lowercased() | Все буквы строчные | "HELLO".lowercased() | "hello" |
capitalized | Первая буква каждого слова заглавная | "hello world".capitalized | "Hello World" |
2. Проверка содержимого
| Метод | Что делает | Пример | Результат |
|---|---|---|---|
isEmpty | Проверяет, пустая ли строка | "".isEmpty | true |
contains("текст") | Содержит ли строка указанный текст | "Привет".contains("иве") | true |
hasPrefix("текст") | Начинается ли с указанного текста | "Свифт".hasPrefix("Св") | true |
hasSuffix("текст") | Заканчивается ли указанным текстом | "программирование".hasSuffix("ние") | true |
3. Поиск и замена
| Метод | Что делает | Пример | Результат |
|---|---|---|---|
replacingOccurrences(of: "что", with: "на что") | Заменяет все вхождения | "кот кот".replacingOccurrences(of: "кот", with: "пёс") | "пёс пёс" |
trimmingCharacters(in: .whitespaces) | Удаляет пробелы в начале и конце | " текст ".trimmingCharacters(in: .whitespaces) | "текст" |
4. Разделение и объединение
| Метод | Что делает | Пример | Результат |
|---|---|---|---|
split(separator: "символ") | Разделяет строку на массив строк | "a,b,c".split(separator: ",") | ["a", "b", "c"] |
joined(separator: "разделитель") | Объединяет массив строк в одну | ["a", "b"].joined(separator: "-") | "a-b" |
5. Доступ к символам
| Метод/Свойство | Что делает | Пример | Результат |
|---|---|---|---|
count | Количество символов | "Привет".count | 6 |
first | Первый символ (Optional) | "Привет".first | "П" |
last | Последний символ (Optional) | "Привет".last | "т" |
🔑 Ключевой момент: В Swift нельзя просто взять символ по индексу, как в других языках. Нужно использовать специальные индексы строк (String.Index). Это связано с Unicode — символы могут занимать разное количество байт.
Примеры кода — от простого к сложному
Пример 1: Приветствие с заглавной буквы
// Самый простой пример — делаем первую букву заглавной
let имяПользователя = "мария"
// Используем метод capitalized — он делает заглавной первую букву каждого слова
let приветствие = "Привет, " + имяПользователя.capitalized + "!"
print(приветствие) // Выведет: "Привет, Мария!"
// Объяснение:
// 1. Создаём переменную с именем в нижнем регистре
// 2. Вызываем .capitalized — он возвращает новую строку "Мария"
// 3. Склеиваем три части: "Привет, " + "Мария" + "!"
// 4. Печатаем результат
Пример 2: Проверка пароля на сложность
// Проверяем, что пароль содержит хотя бы одну заглавную букву
let пароль = "Swift123"
// Используем метод contains для поиска подстроки
let содержитЗаглавную = пароль.contains("S") // true
let содержитЦифру = пароль.contains("1") // true
// Более умная проверка — ищем любую заглавную букву
let заглавныеБуквы = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
var естьЗаглавная = false
// Перебираем каждую заглавную букву
for буква in заглавныеБуквы {
if пароль.contains(буква) {
естьЗаглавная = true
break // Как нашли — выходим из цикла
}
}
print("Пароль содержит заглавную букву: (естьЗаглавная)")
// Выведет: "Пароль содержит заглавную букву: true"
Пример 3: Очистка текста от лишних пробелов
// Пользователь ввёл текст с лишними пробелами
let грязныйТекст = " Привет, мир! "
// Шаг 1: Удаляем пробелы в начале и конце
let безПробеловПоКраям = грязныйТекст.trimmingCharacters(in: .whitespaces)
print("После удаления пробелов по краям: '(безПробеловПоКраям)'")
// Выведет: "Привет, мир!"
// Шаг 2: Заменяем множественные пробелы на один
// Разделяем строку по пробелам
let слова = безПробеловПоКраям.split(separator: " ")
print("Массив слов: (слова)") // ["Привет,", "мир!"]
// Шаг 3: Склеиваем обратно с одним пробелом
let чистыйТекст = слова.joined(separator: " ")
print("Чистый текст: '(чистыйТекст)'")
// Выведет: "Привет, мир!"
Пример 4: Поиск и замена в тексте
// Представь, что мы пишем цензуру для комментариев
let оригинал = "Этот фильм просто ужасный и отвратительный!"
// Список плохих слов
let плохиеСлова = ["ужасный", "отвратительный"]
// Создаём копию текста для изменений
var исправленныйТекст = оригинал
// Заменяем каждое плохое слово на звёздочки
for слово in плохиеСлова {
// Создаём строку из звёздочек той же длины
let замена = String(repeating: "*", count: слово.count)
// Заменяем все вхождения плохого слова
исправленныйТекст = исправленныйТекст.replacingOccurrences(of: слово, with: замена)
}
print("Оригинал: (оригинал)")
print("Исправлено: (исправленныйТекст)")
// Выведет: "Этот фильм просто ****** и **************!"
Пример 5: Работа с эмодзи и Unicode
// Swift отлично работает с эмодзи!
let приветствиеСЭмодзи = "Привет! 👋 Как дела? 😊"
// Считаем символы — эмодзи считается как один символ
print("Количество символов: (приветствиеСЭмодзи.count)")
// Выведет: 20 (каждый эмодзи — это один символ)
// Проверяем, содержит ли строка определённый эмодзи
let естьПомахивание = приветствиеСЭмодзи.contains("👋")
print("Есть помахивание: (естьПомахивание)") // true
// Получаем первый символ
if let первыйСимвол = приветствиеСЭмодзи.first {
print("Первый символ: (первыйСимвол)") // "П"
}
// Получаем последний символ
if let последнийСимвол = приветствиеСЭмодзи.last {
print("Последний символ: (последнийСимвол)") // "😊"
}
Пример 6: Разбор email-адреса
// Разбираем email на части
let email = "user@example.com"
// Проверяем, что это похоже на email
let содержитСобаку = email.contains("@")
let содержитТочку = email.contains(".")
if содержитСобаку && содержитТочку {
print("Похоже на валидный email")
// Разделяем по символу @
let части = email.split(separator: "@")
if части.count == 2 {
let имяПользователя = String(части[0])
let домен = String(части[1])
print("Имя пользователя: (имяПользователя)") // "user"
print("Домен: (домен)") // "example.com"
// Проверяем домен верхнего уровня
if домен.hasSuffix(".com") {
print("Это коммерческий домен")
}
}
} else {
print("Некорректный email")
}
Пример 7: Форматирование текста для вывода
// Создаём красивый вывод данных
let имя = "Алексей"
let возраст = 25
let город = "Москва"
// Используем многострочный литерал и интерполяцию
let профиль = """
👤 Имя: (имя)
🎂 Возраст: (возраст) лет
📍 Город: (город)
"""
print(профиль)
// Выведет:
// 👤 Имя: Алексей
// 🎂 Возраст: 25 лет
// 📍 Город: Москва
// Дополнительно: выравнивание с помощью padding
let выровненныйТекст = "Имя".padding(toLength: 10, withPad: " ", startingAt: 0) + ": (имя)"
print(выровненныйТекст) // "Имя : Алексей"
Сравнение с Python: чем похоже и чем отличается
Если ты уже знаешь Python или планируешь учить его потом, вот сравнение:
| Операция | Swift | Python | Примечание |
|---|---|---|---|
| Заглавные буквы | "текст".uppercased() | "текст".upper() | Разные названия методов |
| Разделение строки | "a,b".split(separator: ",") | "a,b".split(",") | В Python split возвращает список, в Swift — массив |
| Объединение | массив.joined(separator: "-") | "-".join(массив) | Синтаксис reversed! |
| Замена | .replacingOccurrences(of: "a", with: "b") | .replace("a", "b") | В Python метод называется replace |
| Проверка начала | .hasPrefix("текст") | .startswith("текст") | Разные названия |
| Проверка конца | .hasSuffix("текст") | .endswith("текст") | Разные названия |
| Длина строки | строка.count | len(строка) | В Swift это свойство, в Python — функция |
| Доступ по индексу | строка[строка.index(...)] | строка[0] | В Swift сложнее из-за Unicode |
| Срезы (substring) | строка[диапазон] | строка[1:3] | В Swift нужно указывать тип String.Index |
🌟 Совет: Если ты переходишь с Python на Swift, запомни главное отличие — в Swift строки это не просто массивы символов. Они работают с Unicode правильно, но требуют больше кода для простых операций с индексами.
Типичные ошибки и подводные камни
Ошибка 1: Забываешь, что методы возвращают новую строку
// ❌ Неправильно
var текст = "привет"
текст.uppercased() // Результат никуда не сохраняется!
print(текст) // Выведет "привет" — строка не изменилась
// ✅ Правильно
var текст2 = "привет"
текст2 = текст2.uppercased() // Сохраняем результат
print(текст2) // Выведет "ПРИВЕТ"
Ошибка 2: Путаешь count с length
// ❌ Неправильно — в Swift нет свойства length
let строка = "Привет"
// print(строка.length) // Ошибка компиляции!
// ✅ Правильно — используем count
print(строка.count) // 6
Ошибка 3: Пытаешься обратиться к символу по индексу как в Python
// ❌ Неправильно
let слово = "Swift"
// let первый = слово[0] // Ошибка! Так нельзя
// ✅ Правильно — используем индекс строки
let первыйИндекс = слово.startIndex
let первыйСимвол = слово[первыйИндекс]
print(первыйСимвол) // "S"
// Или используем свойство first
if let первый = слово.first {
print(первый) // "S"
}
Ошибка 4: Забываешь про Optional при использовании first/last
// ❌ Неправильно — first возвращает Optional
let пустаяСтрока = ""
// let символ = пустаяСтрока.first // Тип — Character? (Optional)
// ✅ Правильно — используем if let
if let символ = пустаяСтрока.first {
print("Первый символ: (символ)")
} else {
print("Строка пустая")
}
Ошибка 5: Путаешь split с components
// split возвращает массив Substring, а не String
let текст = "яблоко,груша,банан"
let части = текст.split(separator: ",")
print(type(of: части[0])) // Substring, а не String
// Если нужны String, конвертируй:
let строки = части.map { String($0) }
print(type(of: строки[0])) // String
Лучшие практики и советы профессионалов
1. Используй многострочные литералы для длинного текста
// Плохо — длинная строка в одну линию
let длинныйТекст = "Это очень длинный текст, который не помещается на экране и его трудно читать, особенно когда нужно что-то исправить"
// Хорошо — используем многострочный литерал
let хорошийТекст = """
Это очень длинный текст,
который теперь легко читать,
потому что он разбит на строки.
"""
2. Всегда проверяй строки на пустоту перед обработкой
// Плохо — может упасть с ошибкой
func первыйСимвол(_ текст: String) -> Character {
return текст.first! // Force unwrap — опасно!
}
// Хорошо — безопасная проверка
func безопасныйПервыйСимвол(_ текст: String) -> Character? {
guard !текст.isEmpty else {
return nil
}
return текст.first
}
3. Используй raw strings для регулярных выражений
// Без raw strings — много экранирования
let сложныйШаблон = "\d{3}-\d{2}-\d{2}"
// С raw strings — чище и понятнее
let простойШаблон = #"d{3}-d{2}-d{2}"#
4. Группируй методы для читаемости
// Плохо — всё в одну строку
let результат = текст.lowercased().trimmingCharacters(in: .whitespaces).capitalized
// Хорошо — разбиваем на шаги
let очищенный = текст.trimmingCharacters(in: .whitespaces)
let вНижнемРегистре = очищенный.lowercased()
let красивый = вНижнемРегистре.capitalized
5. Используй extension для своих методов
// Создаём своё расширение для строк
extension String {
// Метод, который проверяет, является ли строка email'ом
func isValidEmail() -> Bool {
return self.contains("@") && self.contains(".")
}
// Метод, который обрезает строку до определённой длины
func truncated(to длина: Int) -> String {
guard self.count > длина else { return self }
return String(self.prefix(длина)) + "..."
}
}
// Используем
let email = "test@example.com"
print(email.isValidEmail()) // true
let длинный = "Это очень длинный текст"
print(длинный.truncated(to: 10)) // "Это очень д..."
Вопросы для самопроверки
-
Вопрос: Какой метод нужно использовать, чтобы сделать все буквы в строке заглавными?
Ответ:uppercased(). Например:"привет".uppercased()вернёт"ПРИВЕТ". -
Вопрос: Чем отличается
containsотhasPrefix?
Ответ:containsпроверяет, есть ли подстрока в любом месте строки.hasPrefixпроверяет только начало строки. -
Вопрос: Почему в Swift нельзя написать
строка[0]для получения первого символа?
Ответ: Потому что Swift использует Unicode, и символы могут занимать разное количество байт. Нужно использоватьString.Indexили свойстваfirst/last. -
Вопрос: Что вернёт
" текст ".trimmingCharacters(in: .whitespaces)?
Ответ:"текст"— удалит пробелы в начале и конце строки. -
Вопрос: Как разделить строку "яблоко,груша,банан" на массив строк?
Ответ: Использоватьsplit(separator: ","). Результат:["яблоко", "груша", "банан"]. -
Вопрос: В чём разница между
countиlengthв Swift?
Ответ: В Swift нет свойстваlength. Используется толькоcount. -
Вопрос: Как заменить все вхождения слова "кот" на "пёс" в строке?
Ответ: ИспользоватьreplacingOccurrences(of: "кот", with: "пёс"). -
Вопрос: Что такое Optional и почему
firstвозвращает Optional?
Ответ: Optional — это тип, который может содержать значение или nil.firstвозвращает Optional, потому что строка может быть пустой. -
Вопрос: Как в Swift объединить массив строк в одну строку с разделителем?
Ответ: Использоватьjoined(separator: "-"). Например:["a", "b"].joined(separator: "-")вернёт"a-b". -
Вопрос: Почему в Swift строки называются иммутабельными?
Ответ: Потому что методы строк не изменяют исходную строку, а возвращают новую. Это делает код безопаснее и предсказуемее.
Итог и что изучить дальше
Мы прошли большой путь! Теперь ты знаешь:
- Что строки — это не просто текст, а мощные объекты с методами
- Как изменять регистр, искать, заменять, разделять и объединять строки
- Как работать с Unicode и эмодзи
- Какие ошибки чаще всего допускают новички
- Как писать чистый и безопасный код со строками
Это только начало. Строки в Swift — огромная тема. Вот что стоит изучить дальше:
- String.Index — научись работать с индексами строк. Это ключ к гибкой работе с текстом.
- Substring — узнай, чем отличается Substring от String и когда их использовать.
- Регулярные выражения (NSRegularExpression) — для сложного поиска и замены текста.
- Formatter (NumberFormatter, DateFormatter) — для красивого форматирования чисел и дат в строках.
- AttributedString — для работы с форматированным текстом (разные цвета, шрифты).
- Encoding (UTF-8, UTF-16) — как строки хранятся в памяти и конвертируются.
🎯 Главный совет: Не пытайся запомнить все методы сразу. Запомни основные (uppercased, contains, split, joined, replacingOccurrences) и всегда держи под рукой документацию Apple. Практика — лучший способ запомнить. Пиши маленькие программы, которые работают с текстом: анализатор паролей, форматировщик текста, простой поисковик.
Ты теперь не просто знаешь методы строк — ты понимаешь, как они работают изнутри. А это важнее, чем заучивание синтаксиса. Удачи в программировании! 🚀