【问题标题】:Why strings cannot be indexed by integer values为什么字符串不能被整数值索引
【发布时间】:2016-10-18 00:49:50
【问题描述】:

我了解到 Swift 字符串不能由整数值索引。我记住了它,我使用了规则。但我从来没有完全理解它背后的机制。

来自官方文档的解释如下

"不同的字符可能需要不同数量的内存来存储,因此为了确定哪个字符位于特定位置,您必须从该字符串的开头或结尾遍历每个 Unicode 标量。因此, Swift 字符串不能被整数值索引"

读了好几遍,还是不太明白。谁能解释一下为什么 Swift String 不能被整数值索引?

非常感谢

【问题讨论】:

  • developer.apple.com/library/ios/documentation/Swift/Conceptual/… - 这是你正在谈论的话题。至于我,将很难比你从头到尾阅读这个主题更清楚地解释。
  • 快速提示,不是完整的解释:Swift 字符串尊重 unicode,例如,一些表情符号是“组合”字符,它们显示为一个字符,但实际上最多可以使用四个真实字符 -只是我们看不到,显示的时候几个字符合二为一。这就是为什么我们不能依赖 Swift 中字符串中字符的“索引”。
  • @Moritz,这解释了为什么不能通过将整数索引映射到内存中出现的相应 unicode 代码点来实现整数索引,但这并不妨碍实现@987654323 的接口@ 对应于 myString 中的第 7 个规范符号。您的提示是绝对正确的,但以上是我(可能还有其他人)查找问题的原因。
  • “因此,Swift 字符串不能被整数值索引。” ...我觉得有趣的是we end up using integers,从startIndex 计算索引,例如,第三个字符从let start = string.index(string.startIndex, offsetBy: 2) 开始。我理解其中的原理,但这并不能证明增加的复杂性是合理的。

标签: string swift


【解决方案1】:

字符串作为字节数组存储在内存中。

一个给定的字符可能需要 1 到 4 个字节作为基本代码点,外加任意数量的组合变音符号。

例如,é 需要 2 个字节。

现在,如果您有字符串 efghéfgh,要访问第二个字符 (f),对于第一个字符串,该字符位于索引 1 的字节数组中,对于第二个字符串,它位于索引2

为了知道这一点,您需要检查第一个字符。要根据索引访问任何字符,您需要遍历所有前面的字符才能知道每个字符占用多少字节。

【讨论】:

  • 字符可以超过 4 个字节。 "g͇̫͛͆̾ͫ̑͆".characters.count == 1 && "g͇̫͛͆̾ͫ̑͆".lengthOfBytes(using: .utf8) == 17
  • @BrianNickel 是的,我忘了你可以添加变音符号并将它们组合起来。 (在我的示例中,é 也作为独立字符存在)。但是每个代码点都被编码为 1 到 4 个字节。
  • @BrianNickel,为什么我们不能将索引 0 定义为 Swift 的 startIndex 并将索引 N > 0 定义为 Swift 的 index(startIndex, offsetBy: N)?在您的示例中,Swift 是否提供了一种通过索引单独访问 e´ 的方法?
  • @Mike 自从我们讨论后,Swift 内部的事情肯定发生了变化。很多。 String 现在符合 Collection 并且可以像您描述的那样被索引。
  • @Mike 关于您的问题,这取决于字符串。 é 可以用两种方式表示,\u{e9}(重音 e)或 e\u{301}(带有重音组合字符的 e)。在前一种情况下,它是一个字符和一个标量,但 UTF-8 是两个字节。您可以使用str.utf8 访问各个字节。在后一种情况下,它是两个标量、两个 utf-16 字符和 3 个 utf-8 字节。有用于访问每个视图的视图:repl.it/repls/DownrightInsubstantialInterpreter
猜你喜欢
  • 1970-01-01
  • 2016-07-19
  • 2023-02-01
  • 1970-01-01
  • 2022-12-10
  • 1970-01-01
  • 2011-08-29
  • 2019-11-26
  • 2016-07-12
相关资源
最近更新 更多