Как устроены строки в Swift
Вопрос
Почему работа со строками в Swift сложнее, чем в других языках, и как это обходить?
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
`Character` это графемный кластер, длина в памяти разная
Индексация через `String.Index`, а не `Int`; `count` O(n)
Представления `utf8`, `utf16`, `unicodeScalars` для разных задач
`Substring` разделяет память с исходной строкой
Для частого доступа по номеру преобразовать в `Array(s)` или работать с `utf8`
Нативное хранение в UTF-8 с Swift 5
Что могут спросить следом
- Как правильно передать диапазон строки в API с
NSRange? - Почему
"é" == "e\u{301}"даётtrue?
Разбор
Swift честен к Unicode: Character это расширенный графемный кластер, то, что пользователь видит как один символ. Флаг или буква с диакритикой могут занимать несколько скаляров и байтов. Поэтому у строки нет индекса по Int: такой сабскрипт выглядел бы как O(1), а стоил бы O(n). Индексы это String.Index, и count тоже требует прохода. Для разных задач есть представления: utf8 для байтов и быстрого парсинга, utf16 для совместимости с NSString, unicodeScalars для работы со скалярами. Строки сравниваются по канонической эквивалентности, поэтому разные записи «é» равны. Срезы это Substring, они не копируют данные, но держат исходник, так что для хранения я перевожу их в String. На собесе, если задача на символы, я сразу делаю Array(s) или работаю с utf8, чтобы иметь O(1) доступ.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Предыдущий вопрос
Array, Set или Dictionary: как выбрать коллекцию
Следующий вопрос
Почему String.count в Swift работает за O(n)
Ещё по теме «Коллекции и строки»
- Сложность append у Array в Swift
- ContiguousArray и мост с NSArray
- Подсчёт частот в словаре
- Порядок ключей в Dictionary
- Сложность операций коллекций Swift
- String и NSString: длина и индексы
- Как взять n-й символ строки в Swift
- Сколько символов в строке с флагом