正如人们所料,当使用基本数据类型时,Ruby似乎在将变量分配给实例变量时创建变量的副本。换句话说,@name
类中的Person
未指向name
:
class Person
attr_reader :name
def initialize(name)
@name = name
end
end
name = "Michael"
p = Person.new(name)
name = "Peter"
puts p.name
=> "Michael"
如果你对套装做同样的事情,这就不再适用了。实例变量@family
指向family
,对family
的所有更改都会影响@family
:
require 'set'
class Family
attr_reader :people
def initialize(people)
@people = people
end
end
people = Set.new ['Grandfather', 'Father', 'Mother', 'Son', 'Daughter']
family = Family.new(people)
people << 'Grandmother'
puts family.people.include? 'Grandmother'
=> true
为什么Set表现不同?我如何才能最好地创建一个家庭副本? (例如@family = family.dup
)?
答案 0 :(得分:3)
实际上...
Ruby在将变量赋值给实例变量
时似乎创建了变量的副本
以你的想法不正确。看哪
class Person
attr_reader :name
def initialize(name)
@name = name
end
end
name = "Michael"
p = Person.new(name)
name << " Jackson"
puts p.name
# "Michael Jackson"
Ruby确实是一种按值传递的语言,但这些值通常是指向对象的指针。执行name = "Peter"
不会影响实例变量,因为您只是分配了一个新指针。如果你使用一个就地修改对象的方法(比如<<
)你做会影响它,因为两个变量都存储一个指向同一个对象的指针。
你说错了,正确的方法是使用dup
。