在函数中修改哈希变量时会更改哈希变量

时间:2015-09-25 08:19:05

标签: ruby

我正在更改params中的本地变量some_method

def some_method params
  params.object_id       # => 70163816155080 
  params[:name]  = 'bar'
  params.object_id       # => 70163816155080 Why is this not changing after I changed the value?
end

details  = {name: 'foo'}
details.object_id   # => 70163816155080
some_method details
details             # => {:name=>"bar"}

为什么要更改原始变量details? Ruby是否通过引用传递哈希?

2 个答案:

答案 0 :(得分:1)

您的一些不正确的假设

  

我在some_method

中更改了局部变量参数

不,你不是。嗯,是的,您正在更改params某些状态,但该对象未被替换,它保持不变。因此object_id持续存在。如果你要替换对象,那么object_id会改变:

def some_method params
  params = { name: 'bar' } # this is a new object with a new object_id
                           # this assignment won't be visible to the outside
  

为什么在更改值后这没有改变?

有些语言具有不可变数据结构。如果要更改其中的某些数据,则必须生成对象的新版本。 Ruby不是那些语言之一。它的数据结构非常可变。

  

为什么要更改原始变量详细信息

因为这些引用引用了内存中的同一个对象。查看有关"按值传递参考的许多链接"在这里发表了答案和评论。

答案 1 :(得分:0)

Ruby为方便起见,除了Integer,Floats和Symbols之外,通过引用传递所有内容。

<小时/> 更新: 它被称为立即值。

  

立即值不是指针:Fixnum,Symbol,true,false和   nil直接存储在VALUE

您甚至无法为此类值定义方法:

x = :hello
def x.test; end

会引发错误

<小时/> 更多:

例如,Fixnum http://ruby-doc.org/core-2.2.2/Fixnum.html

  

Fixnum对象具有直接价值。这意味着他们什么时候   作为参数分配或传递,实际对象被传递   而不是对该对象的引用。