Range -Swift(譯)

Swift 的range比NSRange更加復雜,并且它在Swift3中并沒有變的更加容易。如果你想更加透徹的明白復雜的原因,你可以閱讀還有。我僅僅告訴你如何創建和使用它們。

Closed Ranges: a...b

這個區間表達式創建了一個Swift的range,該表達式包含元素a和元素b,即使可能為某個類型的最大值(例如Int.max)。關于closed range有兩個類型:CloseRangeCountableCloseRange

  • ClosedRange
    該區間的所有元素是可比較的在Swift中(它們遵守Comparable協議)。
    它會允許你訪問一個集合中某區間的元素。代碼示例:
let myRange: ClosedRange = 1...3
let myArray = ["a", "b", "c", "d", "e"]
myArray[myRange] // ["b", "c", "d"]

但是,ClosedRange是不可計算的(它沒有遵守Sequence協議)。這就意味你不能迭代該區間的值通過一個循環,如果你想循環訪問某個區間的值你需要使用CountableClosedRange類型。

  • CountableClosedRange
    該類型可迭代循環。
//此處換成ClosedRange會報錯
let myRange: CountableClosedRange = 1...3
let myArray = ["a", "b", "c", "d", "e"]
myArray[myRange] // ["b", "c", "d"]
for index in myRange {
    print(myArray[index])
}
Half-Open Range:a..<b

該區間表達式包含a但不包括b,和上面一樣,它也有兩個不同的類型:RangeCountableRange

  • Range
    CloseRange一樣,你可以在一個集合中訪問某區間的元素,示例代碼:
let myRange: Range = 1..<3
let myArray = ["a", "b", "c", "d", "e"]
myArray[myRange] // ["b", "c"]

重要的事再說一次,該類型不可應用于for循環語句!

  • CountableRange
    該類型可應用于for循環語句
let myRange: CountableRange = 1..<3
let myArray = ["a", "b", "c", "d", "e"]
myArray[myRange] // ["b", "c"]
for index in myRange {
    print(myArray[index])
}
NSRange

有的時候你仍然需要使用NSRange在Swift(eg:當你創建富文本的時候),所以了解如何創建它也是非常有用的。

let myNSRange = NSRange(location: 3, length: 2)

在這里強調一下上面的表達式代表的是locationlength,并不是start indexend index。上面的例子和Swift中3..<5看起來非常相似。但是,它倆是不同的,它們并不能互相替換使用。

Ranges with Strings

通過.....<創建ranges是非常方便的方法。代碼示例:

let myRange = 1..<3

比較苦逼的創建方式(作用和上面的代碼是一樣的):

let myRange = CountableRange<Int>(uncheckedBounds: (lower: 1, upper: 3)) // 1..<3
Problem with NSRange

NSRange在截取含有emoji字符的字符串時,會出現錯誤。
代碼示例:

let myNSRange = NSRange(location: 1, length: 3)
let myNSString: NSString = "abcde"
myNSString.substring(with: myNSRange) // "bcd"
let myNSString2: NSString = "a??cde"
myNSString2.substring(with: myNSRange) // "??c"    Where is the "d"!?
Swift Solution

由于以上的原因,在Swift中的字符串你需要使用Range<String.Index>而不是Range<Int>。String Index的計算是基于一個特殊的string,所以它能識別string中含有emoji或者其他的擴展字體集。
代碼示例:

var myString = "abcde"
let start = myString.index(myString.startIndex, offsetBy: 1)
let end = myString.index(myString.startIndex, offsetBy: 4)
let myRange = start..<end
myString.substring(with: myRange) // "bcd"
myString = "a??cde"
let start2 = myString.index(myString.startIndex, offsetBy: 1)
let end2 = myString.index(myString.startIndex, offsetBy: 4)
let myRange2 = start2..<end2
myString.substring(with: myRange2) // "??cd"

原文鏈接

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容