【问题标题】:What does String member 'characters' return?字符串成员“字符”返回什么?
【发布时间】:2016-10-04 15:42:15
【问题描述】:
var str = "Hello"

print(str.characters) // CharacterView(_core: Swift._StringCore(_baseAddress: Optional(0x000000011c9a68a0), _countAndFlags: 5, _owner: nil))

print(str.characters.index(of: "o")!) // Index(_base: Swift.String.UnicodeScalarView.Index(_position: 4), _countUTF16: 1)
print(Array(str.characters)) // ["H", "e", "l", "l", "o"]
print(str.characters.map{String($0)}) //["H", "e", "l", "l", "o"]

for character in str.characters{
    print(character)
}
// H
// e
// l
// l
// o

我阅读了this 的问题。我从 Swift 参考资料中查看了String,发现:var characters: String.CharacterView

但我想知道 str.characters 究竟返回了什么?我怎么能如此轻松地枚举它,或者转换它到一个数组或 map 它然后打印它本身,甚至当它被索引到它时打印如此乱码

我很确定我不明白是因为不了解characterView。我希望是否有人可以在这个问题中对它的作用和含义给出一个外行的概述。

【问题讨论】:

  • 您不仅应该查看CharacterView 文档,还应该查看它所遵循的协议的文档,这些就是您要查找的内容。例如,您可以枚举CharacterView,因为它符合Sequence 协议。
  • @Fantattitude 刚刚重读一遍,还是迷路了

标签: swift string character


【解决方案1】:

str.characters 返回一个String.CharacterView——它在字符串的字符上呈现一个 view,允许您访问它们而无需将内容复制到新缓冲区中(而 Array(str.characters)str.characters.map{...} 会这样做)。

String.CharacterView 本身是一个Collection,它由String.CharacterView.Index(一种不透明的索引类型)索引,并且具有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)

为什么我可以如此轻松地枚举到它,或者将它转换为数组或映射它,然后自己打印它,甚至当它被索引时打印如此乱码

您可以枚举、转换为Arraymap(_:)String.CharacterView,因为它是Collection - 因此符合Sequence,它允许for ... in 循环以及使用map(_:)Array(_:) 构造函数等等。

至于为什么打印出str.characters 会导致“乱码”,这是因为它根本没有通过符合CustomStringConvertibleCustomDebugStringConvertible 来提供自己的自定义文本表示。

【讨论】:

  • 非常感谢您,尤其是您的最后一段。虽然有些线路需要我来回来回。 :)
  • @Honey 乐于助人:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-04
  • 1970-01-01
  • 2014-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多