Просматривая документацию 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.

Не стесняйтесь добавлять свои запросы в раздел ответов.

Спасибо. Продолжай учиться :)

Ссылка: https://docs.swift.org/swift-book