我试图在Swift Playground中实现Boyer-Moore算法,并且我使用了Swift String.Index很多东西并且开始困扰我的原因是为什么索引保持4倍于它应该是的大小。
例如:
let why = "is s on 4th position not 1st".index(of: "s")
Swift Playground中的此代码将生成_compoundOffset 4
而不是1.我确信这样做有理由,但我无法在任何地方找到解释。
这不是解释如何在Swift中获取char索引的任何问题的重复,我知道,我使用index(of :)函数来说明问题。我想知道为什么当使用String.Index时,第二个char的值是4而不是1。
所以我猜它保持索引的方式是私有的,我不需要知道内部实现,它可能与UTF16和UTF32编码有关。
答案 0 :(得分:4)
首先,不要假设_compoundOffset
不是实现细节。 _compoundOffset
是String.Index
的内部属性,它使用位屏蔽在这一个数字中存储两个值:
encodedOffset
,它是以UTF-16代码单位表示的索引的字节偏移量。这个是公开的,可以依赖。在您的情况下,encodedOffset
为1
,因为这是该字符的偏移量,以UTF-16代码单位衡量。请注意,内存中字符串的编码无关紧要! encodedOffset
始终为UTF-16。
transcodedOffset
,它将索引的偏移存储在当前的UTF-16代码单元中。这也是您无法访问的内部属性。对于大多数索引,该值通常为0
,除非您有一个索引到字符串的UTF-8视图中,该视图引用的代码单元不属于UTF-16边界。在这种情况下,transcodedOffset
将以encodedOffset
为单位存储偏移量。
现在为什么_compoundOffset == 4
?因为它将transcodedOffset
存储在两个最低有效位中,并将encodedOffset
存储在62个最高有效位中。因此encodedOffset == 1, transcodedOffset == 0
的位模式为0b100
,即4
。
您可以验证所有这些in the source code for String.Index
。