Swift 3 下标范围适用于第一个集群但不适用于中间

Swift 3 subscript range works for first cluster but not for middle

我想弄清楚为什么以下内容适用于第一个字符串簇(字符)但不适用于第二个。也许 endIndex 不能应用于另一个字符串?

let part = "A"
let full = "ABC"

print(full[part.startIndex ... part.startIndex])                    // "A"
print(full[part.endIndex ... part.endIndex])                        // ""   <- ???
print(full[part.endIndex ... full.index(after: part.endIndex)])     // "B"

bSecond 应该保持 "B",但它是空的。但是一个字符串索引对另一个字符串索引有效的证明是最后一个语句有效。

编辑: 假设 full.hasPrefix(part) 为真。

Swift个谜题。

您不能使用一个字符串的索引来下标另一个字符串 细绳。这可能是偶然的(在你的第一个例子中)或不是 (在你的第二个例子中),或者在运行时崩溃。

在这种特殊情况下,part.endIndex(即 part 字符串的 "one past the end position")returns

String.UnicodeScalarView.Index(_position: 1), _countUTF16: 0)

其中 _countUTF16:(即 "count of this extended grapheme cluster in UTF-16 code units")为零,即它描述 没有范围的位置(在 unicode 标量视图中)。那么

full[part.endIndex ... part.endIndex]

returns 一个空字符串。但这是一个实现细节 (比较 StringCharacterView.swift)。真正的答案只是 "you can't do that".

获得预期(?)结果的安全方法是

let part = "A"
let full = "ABC"

if let range = full.range(of: part) {
    print(full[range]) // A
    if range.upperBound != full.endIndex {
        print(full[range.upperBound...range.upperBound]) // B
    }
}