范围生成中的“..”(双点)和“…”(三点)之间的区别?

我刚开始学习Ruby和Ruby on Rails,并遇到了使用范围的validation代码:

validates_inclusion_of :age, :in => 21..99 validates_exclusion_of :age, :in => 0...21, :message => "Sorry, you must be over 21" 

起初我认为不同之处在于包含端点,但是在我看到的API文档中,它是否是..或者...似乎并不重要:它总是包含端点。

但是,我在irb中做了一些testing,似乎表明..包括两个端点,而...只包括下界而不是上界。 它是否正确?

Range 的文档说:

使用..构造的范围从头到尾包含在内。 那些使用...创build的排除了最终值。

所以a..b就像a <= x <= b ,而a...b就像a <= x < b


请注意,尽pipeto_a在整数范围内给出了一个整数集合,但Range 不是一组值,而只是一对开始/结束值:

 (1..5).include?(5) #=> true (1...5).include?(5) #=> false (1..4).include?(4.1) #=> false (1...5).include?(4.1) #=> true (1..4).to_a == (1...5).to_a #=> true (1..4) == (1...5) #=> false 

以前的文档不包括这个,而是需要阅读Ranges上的Pickaxe部分 。 感谢@MarkAmery( 见下文 )注意此更新。

那是对的。

 1.9.3p0 :005 > (1...10).to_a => [1, 2, 3, 4, 5, 6, 7, 8, 9] 1.9.3p0 :006 > (1..10).to_a => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 

三点语法不太常见,但比(1..10-1).to_a更好

API文档现在描述了这种行为:

使用..构造的范围从头到尾包含在内。 那些使用...创build的排除了最终值。

http://ruby-doc.org/core-2.1.3/Range.html

换一种说法:

 2.1.3 :001 > ('a'...'d').to_a => ["a", "b", "c"] 2.1.3 :002 > ('a'..'d').to_a => ["a", "b", "c", "d"] 

a...b 排除最终值,而a..b 包含最终值。

当使用整数时, a...bperformance为a...b a..b-1

 >> (-1...3).to_a => [-1, 0, 1, 2] >> (-1..2).to_a => [-1, 0, 1, 2] >> (-1..2).to_a == (-1...3).to_a => true 

但是实际上这个范围真的不同。

 >> (-1..2) == (-1...3) => false 

你可以看到这个分步增加。

 >> (-1..2).step(0.5).to_a => [-1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0] >> (-1...3).step(0.5).to_a => [-1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0, 2.5] 

..和…表示一个范围。

只要在irb中看到它:

 ruby-1.9.2-p290 :032 > (1...2).each do puts "p" end p => 1...2 ruby-1.9.2-p290 :033 > (1..2).each do puts "p" end p p