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..<y and x...y produced the same type, Range<T>. 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<Bound> and ClosedRange<Bound> now only require Comparable for the bound. This allows you to create a Range<String>.
  • 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<Int>
Range(r) // converts to Range<Int>

From Range<Bound> and ClosedRange<Bound> now only require Comparable for the bound. This allows you to create a Range<String>.
We can create a String generic Range.

// Range("a"..<"f")
let rangeStr = Range<String>.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<Int>' 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<String.Index>(start: myString.startIndex, end: myString.startIndex.advancedBy(5))
let mySubString = myString.substringWithRange(myRange)   // Hello

// or simply

let myString = "Hello World"
let myRange = myString.startIndex..<myString.startIndex.advancedBy(5)
let mySubString = myString.substringWithRange(myRange)   // Hello

But in the Swift 3.0, the advancedBy is unavailable, we need use index(_:offsetBy:).

let myString = "Hello World"
let myRange = myString.startIndex..<myString.index(myString.startIndex, offsetBy: 5)
let mySubString = myString.substring(with: myRange)   // Hello
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容