这会打印1
:
def sum(i)
i=i+[2]
end
$x=[1]
sum($x)
print $x
这会打印12
:
def sum(i)
i.push(2)
end
$x=[1]
sum($x)
print $x
后者正在修改全局变量$x
。为什么在第二个例子中修改它而不是在第一个例子中?这会发生在类push
的任何方法(不仅仅是Array
)吗?
答案 0 :(得分:4)
在第一个代码段中,您指定新的局部变量来保存返回的$x + [2]
操作的结果,但它不会更改$x
(因为+
方法不会修改接收者对象)。在您的第二个剪辑中,您使用Array#push
方法修改对象(在这种情况下,对象分配给$x
全局变量并作为i
传递到您的sum
方法中它被称为。
答案 1 :(得分:4)
变量范围与此无关。
在第一个代码中,您只使用赋值运算符i
分配给变量=
,而在第二个代码中,您正在修改$x
(也称为{ {1}})使用破坏性方法i
。分配永远不会修改任何对象。它只提供一个引用对象的名称。方法是破坏性的或非破坏性的。像push
,Array#push
这样的破坏性方法会修改接收器对象。像String#concat
,Array#+
这样的非破坏性方法不会修改接收器对象,而是创建一个新对象并返回该对象,或者返回一个已存在的对象。
回答您的评论
是否可以修改接收器取决于接收器对象的类。对于数组,散列和字符串等,据说是 mutable ,可以修改接收器。对于被称为 immutable 的数字等,不可能这样做。
答案 2 :(得分:1)
i.push(2)
将2
追加到i
指向的数组。由于这是$x
指向的相同数组,$x
也会附加2
。
i=i+[2]
创建一个 new 数组并将i
设置为它 - 现在这是一个与$x
指向的数组不同的数组。