2017-02-18 15 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:查看更新。 –