我还在学习 ruby 的基础知识,所以我想我会尝试制作一个乘法表
x = (0..7).to_a
y = []
x.each { y << x }
y
现在是一个 8x8 数组,其中每行相等。 这些只是我不想要的占位符值,因此我尝试遍历数组索引以更改值。
x.each { |i| y[i][i] = i * i }
此时,y
成为一个包含 8 列 [0, 1, 4, 9, 16, ...]
的数组。 我理解为什么我只收到平方值,但我不明白为什么y[1][3]
,例如,当我只期望 [1][1]
、[2][2]
等索引的值被改变时,根本不会被改变。
此外,x
的值也被重新分配给[0, 1, 4, 9, 16, ...]
,即使我从未有意重新分配其值。 通过上面的代码部分,它的值会自动重新分配,我不明白为什么。
我总是可以自己查找另一种制作此类表的方法,但我想了解导致其更改其值的x
发生了什么,以及为什么通过索引迭代的行为不符合预期。 当我可以理解为什么我的简单尝试会产生无效的输出时,我将继续更正确地迭代 2D 数组的每个索引。 我想自己弄清楚这个相当基本的任务,但现在我遇到了障碍。
您放入y
是对完全相同对象的 8 个引用 x
.所以当你改变y[1][1]
时,这与x[1]
是一回事,与y[2][1]
和y[3][1]
等是一回事。
x
的值不会被重新分配。相反,x
是一个 8 元素数组;这个对象是y
八倍的元素,也是x
的值;each
的每次迭代都会修改该数组的内容。
如果你不习惯,这是非常违反直觉的。也许以下令人毛骨悚然的类比会有所帮助。假设你刚刚成立了一个秘密社团,目前你是唯一的成员。(这是一个非常秘密的社团。特别是:你是协会的主席,它的秘书,它的财务主管。你也有工作;比方说,你是Microsoft的首席执行官。
现在,一个敌对秘密社团的成员来了,打断了你秘密社团主席的左脚趾。(显然它不够秘密。另一个人来了,打破了秘书的右膝盖骨。另一个砸碎了掌柜的牙齿。而现在,你瞧,事实证明,Microsoft的首席执行官遭受了所有这些侮辱。这怎么可能?从来没有人告诉任何人打破Microsoft首席执行官的膝盖骨!
当然,这并不难:同一个人可以担任所有这些角色;如果你要求红树林-喉咙摇摆者协会的主席,就像你要求它的秘书一样,或者如果你要求Microsoft的首席执行官,你会得到完全相同的人。
在 Ruby(以及许多其他类似的语言)中,变量与其值之间的关系,或者数组中的位置与持有的事物之间的关系,更像是官方职位与其持有者之间的关系,而不是例如,盒子与其内容之间的关系。完全相同的东西可以是许多变量的值,就像完全相同的人可以是总裁、秘书、财务主管和大维尼-巴一样。