Range class of Swift 3.0
4266 ワード
Explain the usage of the range class in the Migrating to Swift 2.3 or Swift 3 from Swift 2.2 article.
Described as follows:
In support of the collections changes, Range types also had some changes. Previously
Described as follows:
In support of the collections changes, Range types also had some changes. Previously
x.. and x...y
produced the same type, Range
. Now these expressions can produce one of the four types: Range
, CountableRange
, ClosedRange
, CountableClosedRange
. We split Range
into Range
and ClosedRange
types to allow closed ranges that include the maximum value of the type (for example, 0...Int8.max
works now). The plain range types and their ~Countable counterparts differ in the capabilities: Range
and ClosedRange
now only require Comparable
for the bound. This allows you to create a Range
. Range
and ClosedRange
can’t be iterated over (they are not collections anymore), since a value that is merely Comparable
cannot be incremented. CountableRange
and CountableClosedRange
require Strideabe
from their bound and they conform to Collection
so that you can iterate over them.
The ..<
and ...
operators try to do the right thing and return the most capable range, so that code like for i in 1..<10
infers a CountableRange
and continues to work. If you have a variable that is typed as one range type, and you need to pass it to an API that accepts a different type, use the initializers on range types to convert: var r = 0..<10 // CountableRange
Range(r) // converts to Range
From Range
and ClosedRange
now only require Comparable
for the bound. This allows you to create a Range
. We can create a String generic Range. // Range("a"...init(uncheckedBounds: ("a", "f"))
rangeStr.contains("b") // true
From Range
and ClosedRange
can’t be iterated over (they are not collections anymore), since a value that is merely Comparable
cannot be incremented. ClosedRange
can't be used for iteration. let closeRange = ClosedRange(uncheckedBounds: (1, 2))
for i in closeRange {
}
// error: type 'ClosedRange' does not conform to protocol 'Sequence'
From CountableRange
and CountableClosedRange
require Strideabe
from their bound and they conform to Collection
so that you can iterate over them. CountableRange
and CountableClosedRange
can be used for iteration. let myAry = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
let countableRange = CountableRange(uncheckedBounds: (1, 2))
for i in countableRange {
myAry[i] // 2
}
let countableCloseRange = CountableClosedRange(uncheckedBounds: (1, 2))
for i in countableCloseRange {
myAry[i] // 2, 3
}
About String and Range: In Swift 2.x, we can do this: let myString = "Hello World"
let myRange = Range(start: myString.startIndex, end: myString.startIndex.advancedBy(5))
let mySubString = myString.substringWithRange(myRange) // Hello
// or simply
let myString = "Hello World"
let myRange = myString.startIndex..
But in the Swift 3.0, the advancedBy
is unavailable, we need use index(_:offsetBy:)
. let myString = "Hello World"
let myRange = myString.startIndex..