如果在IRB控制台中运行以下代码:
arr = [[], 1]
arr[0]<<arr
结果为[[[...], 1]]
。
此后arr[0]
,arr[0][0]
,arr[0][0][0]
等产生相同的输出。
这种情况有道理,因为我无法显示任意数量的嵌套吗?
然而,arr[0][1]
产生的是nil(而不是1
)是什么?
但arr[0][0][1]
打印1
。
arr[0][0][0][1] => nil
然后:
arr[0][0][0][0][1] => 1
等
发生了什么事?实际创建的结构是什么?这个结构的深度有多大? nils来自哪里?
答案 0 :(得分:1)
看看里面是什么
arr[0]
# => [[[...], 1]]
arr[0]
是一个只有一个元素的数组。因此[1]
将不在此数组中并返回nil。
arr[0][0]
# => [[[...]], 1]
arr[0][0]
将进入顶部数组中唯一的一个元素,此元素包含两个值,因此[1]
会找到一个值。
它表现得如此,因为您执行了arr[0] << arr
而不是arr[0] = arr
通过执行arr = [[], 1]; arr[0] << arr
,您没有将arr
设置为arr[0]
,而是将您添加的arr
设置为arr [0]的元素,这是一个数组本身。
如果你没有这样做
arr = ["whatever", 1]
# => ["whatever", 1]
arr[0] = arr
# => [[...], 1]
arr[0][1]
# => 1
arr[0][0][1]
修改强>
回到你的问题,为什么它成为一个递归数组。您没有将arr
的值传递给arr[0]
,而是将其引用。
arr = ["whatever", 1]
# => ["whatever", 1]
arr.object_id
# => 69999412942060
arr[0] = arr
# => [[...], 1]
arr[0].object_id
# => 69999412942060
arr[0].object_id == arr.object_id
# => true
由于arr
和arr[0]
指的是同一个对象,因此你有Ouroboros
如果您只想插入其值,则应首先对其进行deep_copied。
arr = ["whatever", 1]
arr_copy = Marshal.load(Marshal.dump(arr)) # copy the value,
# delete the object reference dependence
arr[0] = arr_copy
puts arr.inspect
# [["whatever", 1], 1] # no infinit recurrence.
答案 1 :(得分:1)
Array#size
也是必不可少的,以证明为什么有时您会看到nil
或1
作为输出:
arr = [[], 1]
arr[0]<< arr
arr.size # => 2
arr # => [[[...]], 1]
arr[0] # => [[[...], 1]]
arr[0].size # => 1
arr[0][1] # => nil
arr[0][0] # => [[[...]], 1]
arr[0][0].size # => 2
arr[0][0][1] # => 1
arr[0][0][0] # => [[[...], 1]]
arr[0][0][0].size # => 1
arr[0][0][0][1] # => nil
arr[0][0][0][0] # => [[[...]], 1]
arr[0][0][0][0].size # => 2
arr[0][0][0][0][1] # => 1