我有这个方法:
def change_value(obj)
puts obj.object_id #70275832194460
obj = nil
puts obj.object_id #8
end
obj = "hi there"
puts obj.object_id #70275832194460
change_value(obj)
puts obj.object_id #70275832194460
puts obj #still 'hi there', while I would expect nil.
为什么如果我们传递对象并更改其值,新值不会在方法之外维护?
答案 0 :(得分:4)
您没有更改对象的值。您正在更改变量的值。虽然它包含String
对象"hi there"
,但它有一个值。当它包含值nil
时,它是不同的(正如Nishu指出的那样,nil.object_id
显然是非随机的。)
重要的一点是obj
change_value
内的obj
另一个变量,其中包含与您调用函数的原始def change_value(inner_var)
puts inner_var.object_id # points to the same string as outer_var
inner_var = nil
puts inner_var.object_id # inner_var is nil now; outer_var still same
end
outer_var = "hi there"
puts outer_var.object_id # points to a string
change_value(outer_var)
puts outer_var.object_id # still points to the string
# (only inner_var is nil, and it doesn't exist any more)
相同的引用。当您更改该变量的引用时,它不会反映在您调用该函数的变量中。更容易看出是否更改了变量名称:
{{1}}
答案 1 :(得分:1)
您的方法命名很差。它名为change_value
,但它实际上并未更改该值,而是更改了引用。由于Ruby是按值传递,而不是按引用传递,因此更改引用不会对调用者执行任何操作。如果您实际 更改了值,您将能够观察到差异:
def change_value(obj)
puts obj.object_id #70275832194460
obj.replace('hi back!')
puts obj.object_id #70275832194460
obj = nil
puts obj.object_id #8
end
obj = 'hi there'
puts obj.object_id #70275832194460
change_value(obj)
puts obj.object_id #70275832194460
puts obj # 'hi back!'
答案 2 :(得分:0)
局部变量的范围在方法定义中。即使您在方法定义中更改了obj
,也不会影响其外部的变量。在change_value
的方法定义之外,obj
仍然引用与之前相同的对象。