【问题标题】:Hash merging behavior哈希合并行为
【发布时间】:2012-02-26 10:04:19
【问题描述】:

这种行为正确吗?我正在运行如下代码:

@a_hash = {:a => 1}
x = @a_hash
x.merge!({:b => 2})

最后,x 的值已按预期更改,但 @a_hash 的值也已更改。我得到 {:a => 1, :b => 2} 作为它们两个的值。这是 Ruby 中的正常行为吗?

【问题讨论】:

    标签: ruby hash ruby-1.8 ruby-enterprise-edition


    【解决方案1】:

    是的,这是 ruby​​(以及大多数其他语言)中的正常行为。 x@a_hash 都是对同一个对象的引用。通过调用merge!,您可以更改该对象,并且该更改通过所有引用它的变量可见。

    如果您不希望这种行为,您不应该使用变异方法(即改用x = x.merge(...))或在变异之前复制对象(即x = @a_hash.dup)。

    【讨论】:

      【解决方案2】:

      @a_hash 是指向 x 的链接。所以如果你不想改变@a_hash,你应该这样做:

      @a_hash = {:a => 1}
      x = @a_hash.clone
      x.merge!({:b => 2})
      

      【讨论】:

      • 完全等价于x = @a_hash.merge(:b => 2)时不建议克隆
      【解决方案3】:

      是的,实例变量 @a_hash 和局部变量 xreference 存储到同一个 Hash 实例,并且当您更改此实例时(使用 mutator 方法 merge! 更改对象地方),这些变量将被评估为相同的值。

      您可能希望使用 merge 方法创建对象的副本并且不更改原始对象:

      @a_hash = {:a => 1}
      x = @a_hash
      y = x.merge({:b => 2})
      # y => {:a => 1, :b => 2}
      # x and @a_hash => {:a => 1}
      

      【讨论】:

      • 啊,好吧。我怀疑这就是正在发生的事情。谢谢。
      猜你喜欢
      • 1970-01-01
      • 2014-04-16
      • 1970-01-01
      • 2016-09-02
      • 2012-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多