使用Beta 3一切正常,现在我得到一个奇怪的错误,我不知道如何解决它。尝试了所有类似问题的解决方案。
这是我的代码:
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
}
}
两条标记线都给了我同样的错误:
键入' String.Index'不符合协议' IntegerLiteralConvertible'
有人能帮助我吗?或者Beta 4被窃听? 谢谢!
答案 0 :(得分:29)
在测试版4中,Swift的String.Index处理再次发生了变化 - 当预计Int
时,您现在无法提供String.Index
。处理它的方法是使用String.Index
方法创建所需的advance
:
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))
}
}
这完全基于确保正确处理Unicode字符串 - 因为不同的Unicode字符可以有不同的大小,纯整数索引会隐藏字符串不是随机访问的事实。
答案 1 :(得分:12)
Swift关于字符串组件和迭代的概念在Beta 4中发生了变化。从the guide开始,我们看到:
Swift的Character类型的每个实例代表一个扩展的字形集群。扩展字形集群是一个或多个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
。为了弄清楚字符串的长度,Swift实际上必须遍历整个字符串并找出实际字形分割的位置,因此需要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
的{{1}}不再可以从整数文字转换:您无法通过指定偏移量对字符串执行随机访问。相反,您可以使用IndexType
和startIndex
在字符串中前进一段距离,例如advance
或str[str.startIndex]
。
或者您可以在此期间定义自己的辅助函数:
str[advance(str.startIndex, distance)]
显然,在未来的更新中可以(并且可能会)进行一些改进。您可能希望file a bug表达您的疑虑。从长远来看,正确支持字形集群可能是一个很好的决定,但它同时使字符串访问更加痛苦。
答案 2 :(得分:6)
适用于Swift 2.0
使用上面的例子:
curPart.substringToIndex(curPart.startIndex.advancedBy(1))