键入' String.Index'不符合协议' IntegerLiteralConvertible'

时间:2014-07-22 06:46:57

标签: ios xcode 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
        }
    }

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

  

键入' String.Index'不符合协议' IntegerLiteralConvertible'

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

3 个答案:

答案 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}}不再可以从整数文字转换:您无法通过指定偏移量对字符串执行随机访问。相反,您可以使用IndexTypestartIndex在字符串中前进一段距离,例如advancestr[str.startIndex]

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

str[advance(str.startIndex, distance)]

显然,在未来的更新中可以(并且可能会)进行一些改进。您可能希望file a bug表达您的疑虑。从长远来看,正确支持字形集群可能是一个很好的决定,但它同时使字符串访问更加痛苦。

答案 2 :(得分:6)

适用于Swift 2.0

使用上面的例子:

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