为什么Ruby数组允许访问无效的索引范围?

3
在 Ruby koans 中有一个问题如下:

可能是重复的:
Ruby 中的数组切片:寻找来自 Rubykoans.com 的不合逻辑行为的解释

其中有以下问题:

def test_slicing_arrays
  array = [:peanut, :butter, :and, :jelly]

  assert_equal _, array[0,1]
  assert_equal _, array[0,2]
  assert_equal _, array[2,2]
  assert_equal _, array[2,20]
  assert_equal _, array[4,0]
  assert_equal _, array[4,100]
  assert_equal _, array[5,0]
end

你必须用正确的语句填写空缺处。前四个断言按照我的预期工作,但是最后三个让我感到困惑。

array[4,0] 返回 []array[4,100] 也是如此。在这一点上,我认为超出数组范围(在这种情况下大于3)的范围只会返回一个空数组。

但是,array[5,0] 返回 nil,这完全让我感到困惑。

有人能解释这种行为吗?


1
请参见https://dev59.com/EHA65IYBdhLWcg3w6DJO。 - nimrodm
希望我在搜索时能找到那个问题 - 谢谢。 - Martin
这是在输入问题时stackoverflow提供的相关问题列表中的第二个(请参见页面右侧边栏)。无论如何,很高兴我能帮到你 :) - nimrodm
1个回答

2

Ruby不是一种静态语言,你不需要预先声明数组的大小。当你为特定元素赋值时,它会自动扩展数组。

通常我们会将元素添加到数组末尾:

array = []       # => []
array << 1       # => [1]
array += [2]     # => [1, 2]
array.push(3)    # => [1, 2, 3]

或者将其推到最前面:
array.unshift(0) # => [0, 1, 2, 3]

为了添加元素,我们需要确保数组在累加值时不会出现间隔。

我们也可以随机添加元素,这可能非常有用:

array[10] = 10 # => 10
array          # => [0, 1, 2, 3, nil, nil, nil, nil, nil, nil, 10]

您遇到的就是这样。


您可以预定义数组的大小,但它仍然是动态的:

ary = Array.new(10, nil) # => [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]
ary[0] = 0               # => 0
ary[10] = 10             # => 10
ary                      # => [0, nil, nil, nil, nil, nil, nil, nil, nil, nil, 10]
ary[12]=12               # => 12
ary                      # => [0, nil, nil, nil, nil, nil, nil, nil, nil, nil, 10, nil, 12]

此外:当需要更严格的行为时,请使用 fetch。如果索引超出数组范围,它可以返回错误(或默认值,或块的结果)。 - steenslag
1
恕我直言,这并没有以初学者需要的清晰度回答问题。重复问题的最佳答案要明确得多。 - Manur
这似乎对提问者的满意度回答了问题。这是衡量标准。 - the Tin Man

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接