负索引如何与`Array# =`一起使用?
我试着看看Array#[]=
是如何工作的,并且玩了:
enum[int] = obj → obj enum[start, length] = obj → obj enum[range] = obj → obj
问题1
我有一个数组b
在0
指数处持有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]
在定义的数组的捕获范围内。
您要求解释器捕获最后一个元素(在这种情况下从前面开始的第一个元素),并尝试调用一个范围,要求它增加数组的大小,并用您请求的任何内容填充它。
令人高兴的是,一切都仍然很好,并且符合要求。 很高兴知道。