【问题标题】:Understanding Ruby class instance variables [duplicate]了解 Ruby 类实例变量 [重复]
【发布时间】:2012-08-27 18:17:33
【问题描述】:

可能重复:
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 方法中使用它?或者你可以吗?我尝试使用它,但它似乎没有按预期工作,我只是对使用哪种技术以及何时使用以及更重要的是为什么感到困惑。

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

【问题讨论】:

  • 您能否更具体地说明哪个失败以及您期望的输出是什么?
  • 这和类实例变量有什么关系?

标签: ruby


【解决方案1】:

版本 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"

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

【讨论】:

  • java中的self和this一样吗?
  • 是的,self 是对“自身”的引用,例如 this
【解决方案2】:

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

【讨论】:

  • 是否应该直接分配给实例变量是模糊的。我强烈支持这一点,不要认为你可以说你应该直接分配给它,因为使用 setter 有很多真正的好处。我认为您可以提出值得直接分配给 ivars 的论点的唯一方法是当您没有设置器时(使用 attr_reader 而不是 attr_accessor)。
  • 嗯...我认为直接分配给 ivars 在类方法中更有意义,因为 ivars 应该是类的实现层的一部分,这是类方法使用的一个(换句话说,我认为 ivars 应该在类方法中被引用,因为它们不应该在类方法之外 - 将类的内部、“实现”、“私有”层与外部、“公共”层分开) .然而,我认识到,在任何给定的上下文中,任何一个在语义上都可能比另一个更有意义。
  • 在这种情况下,我有时会将attr_accessor 放在private 关键字之后。它更丑陋,但随后我得到了使用 setter 的好处——它们对类的好处不如对实例的好处,因为类不太可能继承功能,而且可变类通常不是一个好的想法,因为他们是单身)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-21
  • 2013-03-24
  • 2021-07-29
  • 2013-07-07
  • 2013-11-26
  • 2015-08-13
  • 2013-05-19
相关资源
最近更新 更多