可变值在ruby中无意中重新分配

ac7*_*c7v 1 ruby arrays iteration multidimensional-array

我还在学习红宝石的基础知识,所以我想我会尝试制作一个乘法表

x = (0..7).to_a
y = []
x.each { y << x }
Run Code Online (Sandbox Code Playgroud)

y现在是一个8x8阵列,每行相等.这些只是我不想要的占位符值,所以我尝试迭代数组索引来更改值.

x.each { |i| y[i][i] = i * i }
Run Code Online (Sandbox Code Playgroud)

此时,y成为一个包含8列的数组[0, 1, 4, 9, 16, ...].我理解为什么我只接收平方值,但我不明白为什么y[1][3],例如,当我只希望改变索引的值时[1][1],它[2][2]会被改变.

进而,价值x被重新分配给[0, 1, 4, 9, 16, ...]为好,尽管我从来没有故意重新分配其价值.通过上面的代码部分,它的值会自动重新分配,我无法理解为什么.

我总是可以自己查找另一种制作这样一个表的方法,但是我想了解发生了什么x导致它改变它的值以及为什么迭代遍历索引的行为不符合预期.当我可以理解为什么我更简单的尝试产生无效输出时,我将继续在2D数组的每个索引上更正确地迭代.我想自己弄清楚这个相当基本的任务,但我现在遇到了障碍.

Gar*_*han 5

你输入的y对完全相同的对象的 8个引用x.所以,当你改变y[1][1],那就是同样的事情x[1],这是同样的事情,y[2][1]y[3][1]等.

价值x未被重新分配.相反,x是一个8元素阵列; 这个对象是y八倍的元素,也是价值x; 每次迭代都在each修改该数组的内容.

如果你不习惯它,这是非常违反直觉的.也许以下令人毛骨悚然的类比将有所帮助.假设你刚刚建立了一个秘密社团,目前你是唯一的成员.(这是一个非常秘密的社会.)特别是:你是社会的主席,其秘书和财务主管.你也有工作; 比方说,你是微软的首席执行官.

现在,一个敌对的秘密社团的成员来到并打破了你的秘密社团主席的左脚趾.(显然它不够秘密.)另一个来了,打破了局长的右膝盖骨.另一个人砸碎了财务主管的牙齿.现在,事实证明,微软的首席执行官已经遭受了所有这些侮辱.怎么可能?没有人告诉任何人打破微软首席执行官的膝盖!

当然这并不困难:同一个人可以填补所有这些角色; 如果你要求红树林 - 喉咙 - 摇摆乐协会主席,就好像你要求其秘书,或者你是否要求微软的首席执行官,你会得到完全相同的人.

在Ruby(以及许多其他类似的语言)中,变量与其值之间的关系,或数组中的位置以及持有的东西,更像是官方帖子与其持有者之间的关系,而不是像盒子与其内容之间的关系.完全相同的事情可能是许多变量的价值,就像完全相同的人可以是总统兼秘书,财务主管和大笨蛋一样.