Range class of Swift 3.0


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 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"..<"f")
let rangeStr = Range.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..

你可能感兴趣的:(Range class of Swift 3.0)