2017-02-18 14 views
0

我想弄清楚为什么以下工作在第一个字符串群集(字符),但不是第二个。也许endIndex不能应用于另一个字符串?斯威夫特3下标范围适用于第一个群集,但不适用于中间

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)为true。

斯威夫特拼图。

+1

注意,在大多数情况下,你永远不应该下标给定的集合与另一个集合的指数。尽管有一些例外情况,例如切片和具有不重要索引的集合,例如'Array'。 – Hamish

+1

准备写同样的东西:) - 用'let part =“”'你的代码会崩溃。 –

+0

忘了提及。假设full.hasPrefix(part))为真... – jazzgil

回答

1

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

在此特定情况下,part.endIndex(这是“一个过去的结束位置”为part串)返回

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

_countUTF16:(这是“在UTF-该扩展字形簇的计数16码单元“)为零,即它描述了 位置(在unicode标量视图中),没有范围。然后

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

返回一个空字符串。但是这是一个实现细节 (比较StringCharacterView.swift)。真正的答案只是“你不能那样做”。

一种安全的方式来获得预期的(?)结果是

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 
    } 
} 
+0

感谢@Martin,您的回答很有用,但它不回答为什么part.endIndex在index/after中工作,但不在下标upper range中工作。 – jazzgil

+0

@jazzgil:查看更新。 –