为什么将哈希集更新为变量更新该变量?

我可以将哈希集更新为另一个变量,如下所示:

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? 

你做了两件截然不同的事情。

你的“原始变量”例子:

 a = 'b' d = a a = 'c' 

是一个简单的赋值,因此在第2行的末尾, ad引用同一个对象。 然后在第3行, a分配一个新对象, ad最终引用不同的对象。

你的第一个例子:

 a = {b: 'c'} d = a a[:b] = 'qwerty' 

是一个赋值,然后调用一个方法来改变它的接收器。 第三行也可以写为以下之一,使方法调用更加明确:

 a.[]=(:b, 'qwerty') a.send(:[]=, :b, 'qwerty') 

因此,您将通过变异方法调用的赋值与一系列赋值进行比较。

如果您的第二个示例在以下方面使用了mutator方法:

 a = 'b' # => 'b' d = a # => 'b' a[0] = 'c' # String#[]= alters its receiver # => 'c' d # => 'c' 

然后ad都会改变,因为你没有做一个改变你引用的对象的赋值,你正在改变引用的对象。


这个问题与Ruby是通过引用还是通过值传递并不完全相同 ,接近但不完全。 我确信这是其他几个问题的重复,但我现在找不到它们。 如果有人发现了正确的副本,请告诉我,我会删除它并拔出我的笨锤。

与原语不同,两个变量都指向同一个底层对象。 如果您需要副本,可以使用克隆或dup。