了解Ruby类实例变量

时间:2012-09-02 23:31:39

标签: ruby

  

可能重复:
  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方法中使用它?或者你呢?我尝试使用它并且它似乎没有按预期工作,我只是混淆了使用哪种技术,何时更重要的是为什么

我真的希望有人可以一劳永逸地为我解决这个问题:)

2 个答案:

答案 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 ++中的静态函数)。