简体   繁体   English

类型'String.Index'不符合协议'IntegerLiteralConvertible'

[英]Type 'String.Index' does not conform protocol 'IntegerLiteralConvertible'

With Beta 3 all worked fine, now I get a strange error, and I have no clue how to fix it. 使用Beta 3一切正常,现在我得到一个奇怪的错误,我不知道如何解决它。 Tried all the solutions for similiar problems. 尝试了解类似问题的所有解决方案。

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? 或者Beta 4被窃听? Thanks! 谢谢!

In beta 4, Swift's String.Index handling changed yet again -- you now can't supply an Int when a String.Index is expected. 在测试版4中,Swift的String.Index处理再次发生了变化 - 你现在无法在期望String.Index时提供Int The way to handle it is by creating the String.Index you need using the advance method: 处理它的方法是通过使用advance方法创建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))
    }
}

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字符可以具有不同的大小,纯整数索引将隐藏字符串不是随机访问的事实。

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. Swift的Character类型的每个实例代表一个扩展的字形集群。 An extended grapheme cluster is a sequence of one or more Unicode scalars that (when combined) produce a single human-readable 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⃝. 那是因为c\\u{20DD}组合形成c⃝。 Also notice that we're using countElements . 另请注意我们正在使用countElements In order to figure out the length of the string, Swift actually has to iterate through the whole string and figure out where the actual grapheme divisions are, so it takes O(n) time. 为了弄清楚字符串的长度,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. 正如您的错误所说,另一个问题是StringIndexType不再可以从整数文字转换:您不能通过指定偏移量对字符串执行随机访问。 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)] . 相反,您可以使用startIndexadvance在字符串中向前移动一些距离,例如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 bug with 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. 从长远来看,正确支持字形集群可能是一个很好的决定,但它同时使字符串访问更加痛苦。

For Swift 2.0 对于Swift 2.0

Using the example above: 使用上面的例子:

curPart.substringToIndex(curPart.startIndex.advancedBy(1)) 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM