4

我试着看看是如何Array#[]=工作的,然后玩了一下:

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

问题 1

我有一个数组b保存nil在它的0索引处。

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

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

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

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

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

问题2

我创建了一个 size 数组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]
4

3 回答 3

7

我建议您查看Array 文档中的第一段。它出人意料地说:“负索引被认为是相对于数组末尾的——也就是说,索引 -1 表示数组的最后一个元素,-2 是数组中的倒数第二个元素,因此开。”</p>

这意味着,a[-N]当且仅 . 时,您可以设置元素|N| <= a.size。这就是a = [1,2] ; a[-3] = 3失败的原因(3 > 2)。

另一方面,红宝石数组[可能]没有记录的功能:a[INBOUNDS_IDX..NONSENSE_IDX]=SMTH将在索引之前插入: SMTH INBOUNDS_IDX

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)].)

于 2013-02-24T10:03:32.080 回答
0

观察#1

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

观察#2:

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

于 2013-02-24T08:21:58.680 回答
0

Q1:

一个空数组有 0 个元素,所以当你尝试将它的元素设置为 0 时,使用负索引-1,它会出错。因为负索引从末尾循环遍历数组。

所以 a = []; a[-1] = 3让人无法

a) 获取最后位置的元素,因为它的 null

b) 设置它的值。因为它从未被捕获。

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

a) 抓住第一个元素,

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

请参阅官方 api 文档,特别提到正索引可以增加大小,超过数组开头的负索引会引发错误。

Q2:

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

给定a = [1,2]

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

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

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

令人高兴的是,一切都还好,如所愿。很高兴知道。

于 2013-02-24T09:47:40.330 回答