str.characters
возвращает String.CharacterView
- который представляет собой вид на персонаж струны, что позволяет получить доступ к ним без необходимости копировать содержимое в новый буфер (тогда делать Array(str.characters)
или str.characters.map{...}
бы сделать это).
сам String.CharacterView
является Collection
, который индексируется с помощью String.CharacterView.Index
(непрозрачного типа индекса) и имеет элементы (Unsurprisingly) типа Character
(который представляет расширенные графемы кластера - в общем то, что читатель будет рассматривать «одиночный символ» к быть).
let str = "Hello"
// indexed by a String.Index (aka String.CharacterView.Index)
let indexOfO = str.characters.index(of: "o")!
// element of type Character
let o = str.characters[indexOfO]
// String.CharacterView.IndexDistance (the type used to offset an index) is of type Int
let thirdLetterIndex = str.characters.index(str.startIndex, offsetBy: 2)
// Note that although String itself isn't a Collection, it implements some convenience
// methods, such as index(after:) that simply forward to the CharacterView
let secondLetter = str[str.index(after: str.startIndex)]
Причина, по которой он индексируется с помощью специального String.CharacterView.Index
, а не, например, в Int
, является то, что символы могут быть закодированы с различной длиной байт. Поэтому подпиттинг является потенциально (в случае не-ASCII сохраненных строк) операцией O (n) (требует итерации через закодированную строку). Тем не менее, подписка на Int
естественно кажется, что это должна быть операция O (1) (дешевая, не требует итерации).
str.characters[str.characters.index(str.characters.startIndex, offsetBy: n)] // feels O(n)
str.characters[n] // illegal, feels O(1)
Как это, что я могу перечислить в него так легко, или преобразовать его в массив или отобразить его, но напечатать его самостоятельно или даже при индексируется в него печатает так тарабарщина
Вы можете перечислить, конвертировать в Array
и map(_:)
String.CharacterView
просто потому, что это Collection
- и, следовательно, соответствует Sequence
, что позволяет for ... in
перекручивание, а также использование map(_:)
и Array(_:)
конструктор, между прочим.
А почему распечатывании str.characters
результатов в «бреде» это сводится к тому, что она просто не предоставляет свое собственное пользовательские текстовое представление с помощью соответствия либо CustomStringConvertible
или CustomDebugStringConvertible
.
Вы должны не только смотреть в документации 'CharacterView', но и в документации по протоколам, которые она соответствует, это то, что вы ищете. Например, вы можете перечислить 'CharacterView', потому что он соответствует протоколу' Sequence'. – Fantattitude
@Fantattitude Я просто перечитал его снова, все еще потерял – Honey