我可以将哈希集更新为另一个变量,如下所示:
d = a = {b: 'c'}
a[:b] = 'qwerty'
d # => {:b=>'qwerty'} # What is this magic?
d[:b] = 'blah'
a # => {:b=>'blah'} # And this magic?
为什么在使用原始变量时不会发生这种情况?
d = a = 'b'
a = 'c'
d # =>'b' # Why is it still the same?
答案 0 :(得分:5)
你做了两件非常不同的事情。
你的"原始变量"例如:
a = 'b'
d = a
a = 'c'
是一个简单的赋值,因此在第2行的末尾,a
和d
引用相同的对象。然后在第3行,为a
分配了一个新对象,a
和d
最终引用了不同的对象。
你的第一个例子:
a = {b: 'c'}
d = a
a[:b] = 'qwerty'
是一个赋值,后跟一个调用其接收器的方法的调用。第三行也可以写成以下之一,使方法调用更加明确:
a.[]=(:b, 'qwerty')
a.send(:[]=, :b, 'qwerty')
所以你要将变异方法调用的赋值与一系列赋值进行比较。
如果您的第二个示例在a
上使用了mutator方法:
a = 'b'
# => 'b'
d = a
# => 'b'
a[0] = 'c' # String#[]= alters its receiver
# => 'c'
d
# => 'c'
然后a
和d
都会发生变化,因为您没有执行任务来更改a
引用的对象,您正在更改引用的对象
这个问题并不是Is Ruby pass by reference or by value?的重复,但很接近但并不完整。我确定这是其他几个问题的重复,但我现在无法找到它们。如果有人发现了正确的副本,请告诉我,我会删除它并拔出我的笨锤。
答案 1 :(得分:1)
与原语不同,两个变量都指向同一个底层对象。如果您需要副本,可以使用克隆或复制。