types'String.Index'不符合协议'IntegerLiteralConvertible'
随着Beta 3一切正常,现在我得到一个奇怪的错误,我不知道如何解决它。 尝试了所有类似的问题的解决scheme。
这是我的代码:
if !name.isEmpty { var splitted: [String] = name.componentsSeparatedByString(" ") for curPart in splitted { if !curPart.isEmpty { acronym += curPart.substringToIndex(1) //Error } } if (acronym as NSString).length > 2 { acronym = acronym.substringToIndex(2) //Error } }
两个标记都给了我同样的错误:
types'String.Index'不符合协议'IntegerLiteralConvertible'
有人能帮我吗? 还是Beta 4被窃听? 谢谢!
在testing版4中,Swift的String.Index处理再次发生了变化 – 当需要String.Index
时,您现在无法提供Int
。 处理它的方法是使用advance
方法创build你需要的String.Index
:
if !name.isEmpty { var splitted: [String] = name.componentsSeparatedByString(" ") for curPart in splitted { if !curPart.isEmpty { acronym += curPart.substringToIndex(advance(curPart.startIndex, 1)) } } if countElements(acronym) > 2 { acronym = acronym.substringToIndex(advance(acronym.startIndex, 2)) } }
这一切都基于确保Unicodestring处理正确 – 因为不同的Unicode字符可以有不同的大小,纯整数索引将隐藏string不是随机访问的事实。
在Beta 4中,Swift的string组件和迭代的概念已经发生了变化。从指南中 ,我们看到:
Swift的Charactertypes的每个实例代表一个扩展的字形群集。 一个扩展的字形集群是一个或多个Unicode标量的序列(当组合时)产生一个单一的人类可读的字符。
这有一些有趣的副作用:
let str1 = "abc" let str2 = "\u{20DD}def" countElements(str1) // 3 countElements(str2) // 4 countElements(str1+str2) // 6 ≠ 3+4 !!!
那是因为c
和\u{20DD}
结合形成了c。 另外请注意,我们正在使用countElements
。 为了找出string的长度,Swift实际上必须迭代整个string,并找出实际字形分割的位置,所以需要O(n)次。
我们也可以看到对不同编码的影响:
Array((str1+str2).utf8) // [97, 98, 99, 226, 131, 157, 100, 101, 102] Array((str1+str2).utf16) // [97, 98, 99, 8413, 100, 101, 102]
另一个问题,正如你的错误所述, String
的IndexType
不能再从整型文字中转换:你不能通过指定偏移量来对string进行随机访问。 相反,你可以使用startIndex
和advance
前进一些距离,例如str[str.startIndex]
或str[advance(str.startIndex, distance)]
。
或者您可以在此期间定义您自己的帮助器function:
func at<C: Collection>(c: C, i: C.IndexType.DistanceType) -> C.GeneratorType.Element { return c[advance(c.startIndex, i)] } func take<C: protocol<Collection, Sliceable>>(c: C, n: C.IndexType.DistanceType) -> C.SliceType { return c[c.startIndex..<advance(c.startIndex, n)] } at(str1+str2, 3) // d take(str1+str2, 2) // ab
很显然,在未来的更新中可能(也可能会)会有一些改进。 你可能想要提出一个关于你的问题的错误 。 从长远来看,正确地支持字形集群可能是一个很好的决定,但同时也会让string访问更加痛苦。
对于Swift 2.0
使用上面的例子:
curPart.substringToIndex(curPart.startIndex.advancedBy(1))