Ruby - 按值传递

Sal*_*ler 2 ruby object

有没有办法按值传递对象而不是Ruby中的引用?例如,

class Person
  attr_accessor :name
end
def get_name(obj)
  obj.name = "Bob"
  puts obj.name
end
jack = Person.new
jack.name = "Jack"
puts jack.name
get_name(jack)
puts jack.name
Run Code Online (Sandbox Code Playgroud)

输出应该是

Jack
Bob
Jack
Run Code Online (Sandbox Code Playgroud)

代替

Jack
Bob
Bob
Run Code Online (Sandbox Code Playgroud)

任何帮助,将不胜感激.

Mic*_*ker 5

不, Ruby 通过引用传递,而不是值.

如果需要模拟按值传递,可以使用Ruby的Object#clone方法.在这种情况下,你会做这样的事情:

def get_name(obj)
  new_object = obj.clone
  new_object.name = "Bob"
  puts new_object.name
end
Run Code Online (Sandbox Code Playgroud)

这使得对象的浅拷贝.换句话说,复制了对象的实例变量,但不复制变量引用的对象.如果您需要进行深层复制,可以阅读此Stack Overflow帖子.Ruby没有一方法的方法来进行深拷贝,但该职位介绍如何使用编组反编组,使深层副本.

clonedup工作非常相似,但也有一些差异.根据文件:

对象#克隆

产生的浅表副本OBJ的-the实例变量OBJ被复制,而不是它们所引用的对象.复制obj的冻结和污​​染状态.另请参阅Object#dup下的讨论.

对象#DUP

产生的浅表副本OBJ的-the实例变量OBJ被复制,而不是它们所引用的对象.dup复制obj的污染状态.另请参阅Object#clone下的讨论.通常,clone和dup在后代类中可能具有不同的语义.虽然clone用于复制对象,包括其内部状态,但dup通常使用后代对象的类来创建新实例.

此方法可能具有特定于类的行为.如果是这样,那么该行为将记录在该类的#initialize_copy方法下.

您可以查看dupclone文档.

编辑

虽然我的答案可能给出了OP正在寻找的内容,但对于通过引用或值传递的语义而言,它并不严格正确.有关更多讨论,请参阅此页面上的其他答案和评论.您还可以在此处的评论和本文中查看讨论,以获取更多信息.