Просматривая документацию Swift, я перечислил несколько интересных и важных фактов о строках и символах. Учитывая, что вы знакомы с базовой терминологией, эти факты определенно добавят что-то к вашему багажу знаний.
№1. Строки Swift нельзя индексировать целочисленными значениями напрямую, поскольку один символ Swift может состоять из одной, двух или даже нескольких кодовых точек Unicode.
let string = "With\u{1F496}" print(string) print(string.count) Output With💖 5 Note: \u{1F496} has been considered as 1 character
String.Index
представляет собой индекс символов, который вы можете считать таким же простым, как индексы целочисленного массива. Под капотом каждая уникальная строка должна вычислять индексы своих символов.
* Последовательность символов Юникода для представления другого кода. Кластеры расширенных графем могут состоять из нескольких скаляров Unicode. Это означает, что разные символы - и разные представления одного и того же символа - могут потребовать разного объема памяти для хранения.
Поскольку для 🇺🇸 требуется 2 байта, он состоит из двух кодов масштабирования Unicode (\ u {1F1FA} и \ u {1F1F8}). Однако длину объединенных нескольких кодов масштабирования Unicode, которые представляют один расширенный кластер графем, следует рассматривать как один символ в Swift.
Example #1 let string = "US flag is 🇺🇸" print(string.count) Output 12 Example #2 let string = "US flag is \u{1F1FA}\u{1F1F8}" print(string.count) Output 12 Note - Unicode representation of 🇺🇸 is \u{1F1FA}\u{1F1F8}
# 2. count
свойства String не всегда может совпадать сlength
свойством NSString, содержащего те же персонажи.
let string = "With \u{1F496}" print(string,"\n",string.count) Output With💖 5 let string: NSString = "With \u{1F496}" print(string,"\n",string.length) Output With💖 6
Это связано с тем, что длина
NSString
основана на количестве 16-битных кодовых единиц в представлении строки UTF-16, а не на количестве кластеров расширенной графемы Unicode в строке.
№3. NSString
объекты находятся в куче и всегда передаются по ссылке. Принимая во внимание, что String
является типом значения всякий раз, когда мы передаем его (функции или методу) или он назначается (константе или переменной).
String
сам является структурой в Swift.
Хотя компилятор Swift оптимизирует использование строк, поэтому фактическое копирование происходит только в случае крайней необходимости. Временно он разделяет память исходной строки. Копия в памяти создается только тогда, когда есть какие-либо изменения в скопированной строке.
Если вы хотите получить доступ к
NSString
методам наString
без преобразования, импортируйте платформу Foundation в свой класс. ТипString
Swift связан с классомNSString
Foundation.
№3. Если вы хотите включить специальные символы в строковый литерал, не вызывая их эффекта, добавьте строку между расширенными разделителями (#)
Example #1 let string = #"Include special character \"# Output Include special character \ Note: Without #, you need to use double backward slash like \\ to include \ in your string literal. Example #2 let string = #"Evaluate values in string like \(expression)."# Output Evaluate values in string like \(expression). Example #3 let string #”\(6 * 7) is equal to \#(6 * 7)”# (mix of everything i.e. if you need to evaluate the value as well) Output \(6 * 7) is equal to 42
№4. Многострочные строковые литералы - пробел перед закрывающими кавычками ("""
) указывает Swift, какие пробелы следует игнорировать перед всеми остальными строками.
Вы можете включить двойные кавычки ("
) внутри многострочного строкового литерала, не экранируя его. (ниже пример)
Чтобы включить текст
"""
в многострочную строку, снимите хотя бы одну из кавычек. Вы также можете использовать расширенные разделители (#)
let multilineString = """ First Line "\"" Second Line " """ Output First Line """ Second Line "
# 6. Либо назначьте пустой строковый литерал переменной, либо инициализируйте новый экземпляр String
с инициализатором, оба варианта одинаковы.
var emptyString = “” // empty string literal same as var anotherEmptyString = String() // initializer syntax
# 7. Свойство endIndex
не является допустимым аргументом для нижнего индекса строки, потому что это позиция после последнего символа в строке, а не последнего символа. Если String
пусто, startIndex
и endIndex
равны.
let string = "Hello" string[string.endIndex] // Error string.index(after: string.endIndex) // Error let index = string.index(before: string.endIndex) string[index] // prints o
# 9. Подстроки (созданные с помощью нижнего индекса или такого метода, как prefix(_:)
) не подходят для длительного хранения, поскольку они повторно используют хранение исходной строки, вся исходная строка должна храниться в памяти пока используется любая из его подстрок.
# 10. Каждое сравнение строки или подстроки выполняется на основе расширенных кластеров графем. Два строковых значения считаются равными, если они имеют одинаковые комбинации масштабаторов Unicode или каноническую эквивалентность расширенных кластеров графем каждой строки.
let string1 = "US flag is \u{1F1FA}\u{1F1F8}" let string2 = "US flag is 🇺🇸" print(string1 == string2) Output true
Кластеры расширенных графем канонически эквивалентны, если они имеют одинаковое лингвистическое значение и внешний вид, даже если они за кулисами состоят из разных скаляров Unicode.
Не стесняйтесь добавлять свои запросы в раздел ответов.
Спасибо. Продолжай учиться :)