【问题标题】:Ruby modify hash in "each" block. Pass-by-value subtlety ? [duplicate]Ruby 修改“每个”块中的哈希。传递值的微妙之处 ? [复制]
【发布时间】:2014-12-25 14:20:59
【问题描述】:

根据this question,ruby 是严格按值传递的。不过,我遇到了一个案例,其中包括像这样修改哈希:

h = {"one" => ["un", "ein"], "two"=> ["deux", "zwei"]}
h.each { |k,v| v << "overriden"}

导致:

{"one"=>["un", "ein", "overriden"], "two"=>["deux", "zwei", "overriden"]}

但是,以下行为不同:

h = {"one" => "un", "two"=> "deux"}
h.each { |k,v| v = "overriden"}

导致:

{"one"=>"un", "two"=>"deux"}

我怎么能预料到这一点?

【问题讨论】:

  • 抱歉,我们不会一遍又一遍地回答这个问题。
  • @muistooshort 认真的吗?你可能已经注意到这个问题是关于我如何预测这种行为的。所以实际上这与其他问题不一样。我将它发布在 stackoverflow 上以分享我的经验,并让其他人找到示例,让他们了解传递值模式的微妙之处。您认为我可以将标题更改为问题吗?
  • 是的,在我看来,同样的事情一遍又一遍。如果您愿意,欢迎您让其他人重新打开。
  • 我怎么才能找到这个别人?
  • 您是否认为新标题不会让它一遍又一遍地看起来像同一件事?

标签: ruby pass-by-value


【解决方案1】:

如果您阅读链接的答案中的下一段,它会说:

Ruby 没有任何纯非引用值的概念,因此您当然不能将一个值传递给方法。变量总是对对象的引用。为了得到一个不会从你下面改变的对象,你需要复制或克隆你传递的对象,从而提供一个没有其他人引用的对象。

&lt;&lt; 运算符在原地修改数组。你有一个数组的引用,hash 有那个数组的引用,当数组改变时,它们都指向同一个数组。

当您使用= 时,您正在为变量赋值。在某种程度上,您是在告诉变量引用别的东西,而不是对变量引用的东西做某事。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-16
    • 2015-01-02
    • 2012-04-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多