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

mor*_*t3m 25 xcode ios swift

使用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
        }
    }
Run Code Online (Sandbox Code Playgroud)

两条标记的线都给了我同样的错误:

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

有人能帮我吗?或者Beta 4被窃听?谢谢!

Nat*_*ook 29

在测试版4中,Swift的String.Index处理再次发生了变化 - 你现在无法提供Inta a a String.Indexexpected.处理它的方法是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))
    }
}
Run Code Online (Sandbox Code Playgroud)

这完全基于确保正确处理Unicode字符串 - 因为不同的Unicode字符可以具有不同的大小,纯整数索引将隐藏字符串不是随机访问的事实.


jtb*_*des 12

Swift关于字符串组件和迭代的概念在Beta 4中发生了变化.从指南中我们看到:

Swift的Character类型的每个实例代表一个扩展的字形集群.扩展字形集群是一个或多个Unicode标量的序列(当组合时)产生单个人类可读字符.

这有一些有趣的副作用:

let str1 = "abc"
let str2 = "\u{20DD}def"

countElements(str1)      // 3 
countElements(str2)      // 4
countElements(str1+str2) // 6 ? 3+4 !!!
Run Code Online (Sandbox Code Playgroud)

这是因为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]
Run Code Online (Sandbox Code Playgroud)

另外一个问题,因为你的错误说,是StringIndexType,不再从字面整数转换:你无法通过指定偏移进行串上随机访问.相反,您可以使用startIndexadvance向前移动字符串中的某个距离,例如str[str.startIndex]str[advance(str.startIndex, distance)].

或者您可以在此期间定义自己的辅助函数:

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
Run Code Online (Sandbox Code Playgroud)

显然,在未来的更新中可以(并且可能会)进行一些改进.您可能想要提出问题的错误.从长远来看,正确支持字形集群可能是一个很好的决定,但它同时使字符串访问更加痛苦.


Kel*_*lly 7

对于Swift 2.0

使用上面的例子:

curPart.substringToIndex(curPart.startIndex.advancedBy(1)) 
Run Code Online (Sandbox Code Playgroud)