定义
Range代表’连续‘值的集合。集合中值的范围由Range的起始值和结束值标记。这里的’连续’并非数学中的连续,在读完文章后,相信你会对这个‘连续’有清楚的认识。
创建Range
Ruby提供了2种方式创建Range:
- 常量方式:
(1..4)
表示1,2,3,4构成的值集合;(1...4)
表示1,2,3构成的值集合。 - 对象方式:
Range.new(1,4)
表示1,2,3,4构成的值集合;Range.new(1,4,true)
表示1,2,3构成的值集合。
从上述创建Range的方式中,可以看到,..
(两个点)表示包括结束值,...
(三个点)表示不包括结束值。(1..4)
与Range.new(1,4)
效果一样;(1...4)
与Range.new(1,4,true)
效果一样,true表示不包括结束值。
Range分类
有开始值/结束值的Range
这类Range有明确的边界,如: (1..4)
,开始值是1,结束值是4.
没有开始值的Range
(..4)
和Range.new(nil, 4)
效果一样,表示的都是nil..4
范围;(...4)
和Range.new(nil, 4, true)
效果一样,表示的都是nil...4
范围。这类Range通常用来做数组切片(slice),如:
a = [1, 2, 3, 4]
r = (...2) # => nil...2
a[r] # => [1, 2]
没有结束值的Range
(1..)
和Range.new(1, nil)
效果一样,表示的都是1..
范围;(1...)
和Range.new(1, nil, true)
效果一样,表示的都是1...
范围。这类Range通常用来做数组切片(slice),如:
a = [1, 2, 3, 4]
r = (2..) # => 2..
a[r] # => [3, 4]
注意,针对(1..)
和(1...)
这2种没有结束值的Range,他们的起始值、结束值都相同,但是这2个Range是不同的,如:
r0 = (1..) # => 1..
r1 = (1...) # => 1...
r0.begin == r1.begin # => true
r0.end == r1.end # => true
r0 == r1 # => false
可放入Range的对象
如果一个对象可以放入Range中,这个对象的类一定实现了实例方法<=>
。
-
Ruby中的核心类:Array,String,Time,Integer,Float,Symbol,Numeric,Rational,Complex,Kernel,Module,File::State均实现了
<=>
方法。 -
自定义类
t0 = Time.now # => 2021-09-19 09:22:48.4854986 -0500 t1 = Time.now # => 2021-09-19 09:22:56.0365079 -0500 t2 = Time.now # => 2021-09-19 09:23:08.5263283 -0500 (t0..t2).include?(t1) # => true (t0..t1).include?(t2) # => false
可被迭代的Range
如果一个Range可被迭代,那么Range中的对象的类一定实现了实例方法succ
。
Ruby的核心类中,只有Integer,String和Symbol实现了succ
实例方法。上述提到的其他Ruby核心类,并没有实现succ
实例方法,因此不能被迭代。
Reference
Ruby API - Range(3.2)