跳至内容

范围

一个 范围 表示两个值之间的区间。它通常用范围字面量构造,包含两个或三个点

  • x..y: 两个点表示包含范围,包括 xy 以及它们之间的所有值(在数学中:[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 结尾的范围称为无终点范围。在字面量表示法中,可以省略 nilx.. 是一个从 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]

既是无起点又是无终点的范围是有效的,可以用 ..... 表示,但通常没什么用。