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

jui*_*uil 99 ruby syntax range

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

validates_inclusion_of :age, :in => 21..99
validates_exclusion_of :age, :in => 0...21, :message => "Sorry, you must be over 21"
Run Code Online (Sandbox Code Playgroud)

起初我以为差异的包容端点,但在API文档我进去看了看,它并似乎并不重要,是否是.....:它总是包括端点.

但是,我在irb中进行了一些测试,它似乎表明..包括两个端点,而...只包括下限但不包括上限.它是否正确?

And*_*all 146

Range 文档说明了这一点:

使用..从开始到结束包含的范围构建的范围.使用的那些...排除了最终值.

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


请注意,虽然to_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
Run Code Online (Sandbox Code Playgroud)


文档过去不包含此内容,而是要求阅读关于RangesPickaxe部分.感谢@MarkAmery(见下文)注意此更新.

  • 比上面更好/更少混淆的例子:`(1..10).include?10#=> true`和`(1 ... 10).包括?10#=> false` (11认同)
  • @ValentinVassilev Range不是一组值,但是可以生成它们。`inject`来自[Range`包含的[Enumerable`](http://ruby-doc.org/core/Enumerable.html);`Enumerable`利用了[#Range实现的]#each`(http://ruby-doc.org/core/Range.html#method-i-each)。“ Range#each”生成的列表永远不会包含在“ Range”对象本身内。 (2认同)

Mar*_*ery 7

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

使用..从开始到结束的运行构建的范围。使用创建的那些...排除最终值。

-- 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"] 
Run Code Online (Sandbox Code Playgroud)


Chr*_*ald 5

那是正确的.

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]
Run Code Online (Sandbox Code Playgroud)

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

  • 我认为*更多*点意味着范围代表*更少*值真是奇怪.我想这只是'..`更常见,因此它更少? (11认同)
  • @Andrew:我也是这么想的,但也许是因为更常见的两点变体,因此输入更短? (2认同)