有没有办法按值传递对象而不是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)
任何帮助,将不胜感激.
不, 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没有一方法的方法来进行深拷贝,但该职位介绍如何使用编组和反编组,使深层副本.
clone和dup工作非常相似,但也有一些差异.根据文件:
产生的浅表副本OBJ的-the实例变量OBJ被复制,而不是它们所引用的对象.复制obj的冻结和污染状态.另请参阅Object#dup下的讨论.
产生的浅表副本OBJ的-the实例变量OBJ被复制,而不是它们所引用的对象.dup复制obj的污染状态.另请参阅Object#clone下的讨论.通常,clone和dup在后代类中可能具有不同的语义.虽然clone用于复制对象,包括其内部状态,但dup通常使用后代对象的类来创建新实例.
此方法可能具有特定于类的行为.如果是这样,那么该行为将记录在该类的#initialize_copy方法下.
虽然我的答案可能给出了OP正在寻找的内容,但对于通过引用或值传递的语义而言,它并不严格正确.有关更多讨论,请参阅此页面上的其他答案和评论.您还可以在此处的评论和本文中查看讨论,以获取更多信息.