无意中在 ruby 中重新分配了变量值



我还在学习 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(以及许多其他类似的语言)中,变量与其值之间的关系,或者数组中的位置与持有的事物之间的关系,更像是官方职位与其持有者之间的关系,而不是例如,盒子与其内容之间的关系。完全相同的东西可以是许多变量的值,就像完全相同的人可以是总裁、秘书、财务主管和大维尼-巴一样。

最新更新