范围¶
一个 范围 表示两个值之间的区间。它通常用范围字面量构造,包含两个或三个点
x..y
: 两个点表示包含范围,包括x
和y
以及它们之间的所有值(在数学中:[x, y]
)。x...y
: 三个点表示排除范围,包括x
以及所有直到但不包括y
的值(在数学中:[x, y)
)。
(0..5).to_a # => [0, 1, 2, 3, 4, 5]
(0...5).to_a # => [0, 1, 2, 3, 4]
注意
范围字面量通常用括号括起来,例如,如果它用作调用的接收者。 0..5.to_a
不带括号在语义上等效于 0..(5.to_a)
,因为方法调用和其他运算符比范围字面量具有更高的优先级。
记住哪一个是包含范围,哪一个是排除范围的一个简单方法是将额外的点视为将 y 推得更远,从而将其排除在范围之外。
字面量 x..y
在语义上等效于显式构造函数 Range.new(x, y)
,而 x...y
等效于 Range.new(x, y, true)
。
开始值和结束值不需要是相同类型:true..1
是一个有效的范围,虽然它没什么用,因为 Enumerable
方法不适用于不兼容的类型。它们至少需要是可比较的。
从 nil
开始的范围称为无起点范围,而以 nil
结尾的范围称为无终点范围。在字面量表示法中,可以省略 nil
:x..
是一个从 x
开始的无终点范围,而 ..x
是一个以 x
结尾的无起点范围。
numbers = [1, 10, 3, 4, 5, 8]
numbers.select(6..) # => [10, 8]
numbers.select(..6) # => [1, 3, 4, 5]
numbers[2..] = [3, 4, 5, 8]
numbers[..2] = [1, 10, 3]
既是无起点又是无终点的范围是有效的,可以用 ..
或 ...
表示,但通常没什么用。