Range

2018-08-05  本文已影响44人  大爷的二舅

范围代表的是两个值的区间,它由上下边界进行定义。你可以通过 ..< 来创建一个不包含上边界的半开范围,或者使用 ... 创建同时包含上下边界的闭合范围:

let singleDigitNumbers = 0..<10
Array(singleDigitNumbers)

let lowercaseLetters = Character("a")...Character("z")

半开范围和闭合范围各有所用:

可数范围

范围看起来很自然地会是一个序列或者集合类型,但是可能出乎你的意料,Range 和 ClosedRange 既非序列,也不是集合类型。有一部分范围确实是序列,不然的话,我们就不能实现在 for 循环中对于一个整数范围进行迭代了:

for i in 0..<10 {
    print("\(i)", terminator: " "))
}

之所以能这样做的原因,是因为 0..<10 的类型其实是一个 CountableRange<Int>。CountableRange 和 Range 很相似,只不过它还需要一个附加约束:它的元素类型需要遵守 Strideable 协议 (以整数为步长)。Swift 将这类功能更强的范围叫做可数范围,这是因为只有这类范围可以被迭代。可数范围的边界可以是整数或者指针类型,但不能是浮点数类型,这是由于 Stride 类型中有一个整数的约束。如果你想要对连续的浮点数值进行迭代的话,你可以通过使用 stride(from:to:by) 和 stride(from:through:by) 方法来创建序列用以迭代。Strideable 的约束使得 CountableRange 和 CountableClosedRange 遵守 RandomAccessCollection,于是我们就能够对它们进行迭代了。

部分范围

部分范围 (partial range) 指的是将 ... 或 ..< 作为前置或者后置运算符来使用时所构造的范围。比如,0... 表示一个从 0 开始的范围。这类范围由于缺少一侧的边界,因此被称为部分范围。具体来说,有四种不同的部分范围:

let fromA: PartialRangeFrom<Character> = Character("a")...
let throughZ: PartialRangeThrough<Character> = ...Character("z")
let upto10: PartialRangeUpTo<Int> = ..<10
let fromFive: CountablePartialRangeFrom<Int> = 5...

其中能够计数的只有 CountablePartialRangeFrom 这一种类型,四种部分范围类型中,只有它能被进行迭代。迭代操作会从 lowerBound 开始,不断重复地调用 advanced(by: 1)。如果你在一个 for 循环中使用这种范围,你必须牢记要为循环添加一个 break 的退出条件,否则循环将无限进行下去 (或者当计数溢出的时候发生崩溃)。PartialRangeFrom 不能被迭代,这是因为它的 Bound 不满足 Strideable。而 PartialRangeThrough 和 PartialRangeUpTo 则是因为没有下界而无法开始迭代。

上一篇 下一篇

猜你喜欢

热点阅读