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 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..