了解Ruby类实例变量

Bla*_*man 8 ruby

可能重复:
为什么Ruby setter在课堂上需要"自我"资格?

有人可以解释以下之间的区别,以及为什么它不像人们所期望的那样:

# 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
Run Code Online (Sandbox Code Playgroud)

根据我的理解,在方法中,当您分配时,您必须使用self关键字.你为什么不能在initialize方法中使用它?或者你呢?我尝试使用它,它似乎没有按预期工作,我只是混淆使用哪种技术,什么时候,更重要的是为什么.

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

rob*_*rit 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"
Run Code Online (Sandbox Code Playgroud)

在这里你实际上并没有直接设置@name变量user,而是调用一个名为name=on 的方法user来设置@name你的值.当您attr_accessor在版本#2和#3中进行调用时,它为您定义了该方法.但是在版本#1中您没有调用attr_accessor,因此上面的示例将无效,因为没有name=方法.


小智 0

您不需要在方法中使用 self;对于实例变量,您应该直接使用 @ 进行赋值,就像在版本 1 或 2 中一样。 self 与 Python 中不同;例如,它用于声明类方法(如 C++ 中的静态函数)。