负索引如何与`Array# =`一起使用?

我试着看看Array#[]=是如何工作的,并且玩了:

 enum[int] = obj → obj enum[start, length] = obj → obj enum[range] = obj → obj 

问题1

我有一个数组b0指数处持有nil

 b = [] b[0] # => nil 

我试图在下面的代码中用整数10替换nil

 b[-1] = 10 # => IndexError: index -1 too small for array; minimum: 0 

为什么上面的代码不起作用,但下面的代码呢? 对于大小为1的数组,为什么索引0-1处理方式不同?

 b[0] = 5 # => 5 b[-1] = 10 # => 10 

问题2

我创建了一个大小为2的数组,并执行了以下操作:

 a = [1,2] a[-3] = 3 # => IndexError: index -3 too small for array; minimum: -2 a[-3] = [3] # => IndexError: index -3 too small for array; minimum: -2 a[-3..-4] = [3] # => RangeError: -3..-4 out of range 

我相信负面索引永远不会增加数组的大小,但我不知道为什么。 为什么下面的代码成功了?

 a[-2..-3] = [3,4] #=> [3, 4] 

我建议你看一下Array文档中的第一段。 令人惊讶地说:“假定负索引相对于数组的末尾 – 也就是说,索引-1表示数组的最后一个元素,-2是数组中最后一个元素的下一个元素,因此上。”

这意味着,您可以设置a[-N] th元素,只有|N| <= a.size |N| <= a.size 。 这就是为什么a = [1,2] ; a[-3] = 3 a = [1,2] ; a[-3] = 3失败(3> 2)。

另一方面,[可能]没有记录ruby数组的特性: a[INBOUNDS_IDX..NONSENSE_IDX]=SMTH INBOUNDS_IDX索引之前 插入 SMTH

 a=[1,2] a[2..0]='a' a[2..1]='b' a[2..-100]='c' # ⇒ [1, 2, "c", "b", "a"] a[2..-1]='q' # ⇒ [1, 2, "q"] 

这里的废话意味着“小于INBOUNDS_IDX, 并且不能作为否定符号中的索引处理”(这就是为什么上面例子中a[2..-1]被视为a[2..(a.size - 1)] 。 )

观察#1

-1索引与最后一个元素相关,如果数组没有size [],则在使用一个或多个元素初始化之前不能使用它。

观察#2:

是的,你是对的,负数索引永远不会增加数组的大小,如果只引用数组中的具体现有位置。 不要认为数组是循环的(0索引符合N-1索引),所以你不能使用任何负面索引认为它是有效的

Q1:

空数组有0个元素,因此当您尝试将其元素设置为0时,负索引为-1 ,则会产生错误。 因为负指数从最后通过数组循环。

所以a = []; a[-1] = 3 a = []; a[-1] = 3使得它无法实现

a)将元素放在最后位置,因为它为null

b)设定其价值。 因为它从未被捕获过。

a[0] = 5将起作用,因为你告诉编译器

a)抓住第一个元素,

b)如果不存在则创建一个,然后将其分配给您请求的值。

看官方api doc特别提到正索引可以增长大小,负数索引过去的数组引发错误。

Q2:

以上解释几乎也回答了第二个问题。

给定a = [1,2]

a[-3] = 3导致第一个断点。 您正尝试从末尾访问第3个元素,该元素不存在。 按设计它会崩溃。

a[-2..-3]在定义的数组的捕获范围内。

您要求解释器捕获最后一个元素(在这种情况下从前面开始的第一个元素),并尝试调用一个范围,要求它增加数组的大小,并用您请求的任何内容填充它。

令人高兴的是,一切都仍然很好,并且符合要求。 很高兴知道。