xcode 类型 'String.Index' 不符合协议 'IntegerLiteralConvertible'
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24880604/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Type 'String.Index' does not conform protocol 'IntegerLiteralConvertible'
提问by mort3m
With Beta 3 all worked fine, now I get a strange error, and I have no clue how to fix it. Tried all the solutions for similiar problems.
Beta 3 一切正常,现在我收到一个奇怪的错误,我不知道如何修复它。尝试了所有类似问题的解决方案。
Here is my code:
这是我的代码:
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
}
}
Both marked lines gave me the same error:
两条标记的行都给了我同样的错误:
Type 'String.Index' does not conform protocol 'IntegerLiteralConvertible'
类型 'String.Index' 不符合协议 'IntegerLiteralConvertible'
Can someone help me? Or is Beta 4 bugged? Thanks!
有人能帮我吗?还是 Beta 4 被窃听了?谢谢!
回答by Nate Cook
In beta 4, Swift's String.Index handling changed yet again -- you now can't supply an Int
when a String.Index
is expected. The way to handle it is by creating the String.Index
you need using the advance
method:
在 beta 4 中,Swift 的 String.Index 处理再次发生了变化——您现在无法Int
在 aString.Index
预期时提供 an 。处理它的方法是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))
}
}
This is all based on making sure Unicode strings are handled properly - since different Unicode characters can have different sizes, pure integer indexing would hide the fact that Strings aren't random access.
这一切都基于确保正确处理 Unicode 字符串——因为不同的 Unicode 字符可以有不同的大小,纯整数索引会隐藏字符串不是随机访问的事实。
回答by jtbandes
Swift's notion of string components and iteration has changed in Beta 4. From the guide, we see:
Swift 的字符串组件和迭代概念在 Beta 4 中发生了变化。从指南中,我们看到:
Every instance of Swift's Character type represents a single extended grapheme cluster. An extended grapheme cluster is a sequence of one or more Unicode scalars that (when combined) produce a single human-readable character.
Swift 的 Character 类型的每个实例都代表一个扩展的字素簇。扩展字素簇是一个或多个 Unicode 标量的序列,(组合时)产生单个人类可读的字符。
This has some interesting side effects:
这有一些有趣的副作用:
let str1 = "abc"
let str2 = "\u{20DD}def"
countElements(str1) // 3
countElements(str2) // 4
countElements(str1+str2) // 6 ≠ 3+4 !!!
That's because the c
and \u{20DD}
combine to form c?. Also notice that we're using countElements
. In order to figure out the length of the string, Swift actually has to iterate through the whole stringand figure out where the actual grapheme divisions are, so it takes O(n) time.
那是因为c
和\u{20DD}
结合形成 c?。另请注意,我们正在使用countElements
. 为了计算字符串的长度,Swift 实际上必须遍历整个字符串并找出实际的字素划分位置,因此需要 O(n) 时间。
We can also see the effect on different encodings:
我们还可以看到对不同编码的影响:
Array((str1+str2).utf8) // [97, 98, 99, 226, 131, 157, 100, 101, 102]
Array((str1+str2).utf16) // [97, 98, 99, 8413, 100, 101, 102]
Another issue, as your error says, is that String
's IndexType
is no longer convertible from an integer literal: you can't perform random access on the string by specifying an offset. Instead, you can use startIndex
and advance
to move forward some distance in the string, for example str[str.startIndex]
or str[advance(str.startIndex, distance)]
.
正如您的错误所说,另一个问题是String
'sIndexType
不再可从整数文字转换:您无法通过指定偏移量对字符串执行随机访问。相反,您可以使用startIndex
和advance
在字符串中向前移动一段距离,例如str[str.startIndex]
或str[advance(str.startIndex, distance)]
。
Or you can define your own helper functions in the meantime:
或者您可以同时定义自己的辅助函数:
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
Obviously there are some improvements that could (and probably will) be made in future updates. You may want to file a bugwith your concerns. In the long run, supporting grapheme clusters correctly was probably a good decision, but it makes string access a little more painful in the meantime.
显然,在未来的更新中可以(并且可能会)进行一些改进。您可能想提交一个带有您关注的错误。从长远来看,正确支持字素集群可能是一个不错的决定,但同时它使字符串访问变得更加痛苦。
回答by Kelly
For Swift 2.0
对于 Swift 2.0
Using the example above:
使用上面的例子:
curPart.substringToIndex(curPart.startIndex.advancedBy(1))