可能重复:
Array slicing in Ruby: looking for explanation for illogical behaviour (taken from Rubykoans.com)
我有一个简单的数组对象:
array = [:peanut, :butter, :and, :jelly]
它的长度显然是4!
现在,看看这些陈述:
array[4,0] == []
array[5,0] == nil
从第4个索引切片数组,它返回一个空数组,但是从第5个元素开始,它返回nil。为什么会这样?
答案 0 :(得分:1)
slice(start, length)
(当您访问array[]
时调用的方法)从索引length
开始返回长度为start
的数组。这解释了为什么array[4,0]
返回[]
。
然而,这种方法存在一个极端情况。 The Ruby documentation of slice说:
如果索引(或起始索引)超出范围,则返回nil。
在第二个示例中,5
超出了array
的范围。这会导致该方法返回nil
。
答案 1 :(得分:1)
有一秒钟,我以为你发现了一个错误,但我想我可以解释这个行为。您提供给slice
的起始索引在>>该索引处的元素之前仅被视为。因此,索引4
被认为是数组的 end (就在索引4
之前,就在索引3
之后)。以下示例应明确说明:
> [1,2,3,4][0, 3]
# => [1, 2, 3]
> [1,2,3,4][1, 3]
# => [2, 3, 4]
> [1,2,3,4][2, 3]
# => [3, 4]
> [1,2,3,4][3, 3]
# => [4]
> [1,2,3,4][4, 3]
# => []
> [1,2,3,4][5, 3]
# => nil
答案 2 :(得分:1)
实际上,你发现“奇怪”的东西的原因应该始终在于源代码。我只是从https://github.com/ruby/ruby/blob/trunk/range.c
中选择相关的代码段...
if (beg < 0) {
beg += len;
if (beg < 0)
goto out_of_range;
}
if (err == 0 || err == 2) {
if (beg > len)
goto out_of_range;
if (end > len)
end = len;
}
...
此处,如果起始索引beg
小于-length,则返回范围Qnil
。否则,如果起始索引大于数组的长度(代码片段中为len
),则它也会返回超出范围(Qnil
)。注意这里,它大于不大于或等于,这就是为[]
得到array[4,0]
的原因(虽然4超出范围)但nil
为array[5,0]