可能重复:
Why do Ruby setters need “self.” qualification within the class?
有人可以解释以下内容之间的区别,以及为什么它不像人们期望的那样:
# version #1
class User
def initialize(name, age)
@name = name
@age = age
end
end
#version #2
class User
attr_accessor :name, :age
def initialize(name, age)
@name = name
@age = age
end
end
#version #3
class User
attr_accessor :name, :age
def initialize(name, age)
self.name = name
self.age = age
end
end
根据我的理解,在方法中,在分配时,您必须使用self
关键字。为什么不能在initialize
方法中使用它?或者你呢?我尝试使用它并且它似乎没有按预期工作,我只是混淆了使用哪种技术,何时更重要的是为什么。
我真的希望有人可以一劳永逸地为我解决这个问题:)
答案 0 :(得分:16)
版本1:构造函数创建两个实例变量@name
和@age
。这两个变量是私有的(和所有Ruby实例变量一样),所以你不能在类之外访问它们。
版本2:与#1完全相同,只是您还要为这两个变量定义getter和setter方法。 attr_accessor
所做的是为每个参数创建两个方法,允许您使用相同的名称获取/设置实例变量的值。
版本3:与#2完全相同,只是在构造函数中你没有直接设置实例变量,而是调用User#name=
和User#age=
方法来设置你的值实例变量而不是直接设置它们。
为了阐明直接设置实例变量和调用setter方法之间的区别,请考虑以下示例:
user = User.new "Rob", 26
user.name = "Joe"
此处您实际上并未直接设置@name
的{{1}}变量,而是在user
上调用name=
的方法,该方法设置{{1}的值}} 为了你。当您在版本#2和#3中调用user
时,它为您定义了该方法。但是,在版本#1中,您没有调用@name
,因此上面的示例无效,因为没有attr_accessor
方法。
答案 1 :(得分:0)
您不需要在方法中使用self;对于实例变量,你应该直接用@分配,就像在版本1或2中一样。self不像Python;例如,它用于声明一个类方法(比如C ++中的静态函数)。