attr_accessor与attr_reader的区别以及实例变量

10

有人能告诉我以下两者之间的区别吗?(如果有的话)

class Car
  attr_accessor :engine
  def initialize(engine)
    self.engine = engine
  end
end

并且

class Car
  attr_reader :engine
  def initialize(engine)
    @engine = engine
  end
end

他们是不是基本相同的?
4个回答

19

attr_accessor定义了gettersetterattr_reader只定义了getter

class Car
  attr_reader :engine
  def initialize(engine)
    @engine = engine
  end
end

Car.instance_methods(false) # => [:engine]

使用上述代码,您仅定义了def engine; @engine ;end

class Car
  attr_accessor :engine
  def initialize(engine)
    self.engine = engine
  end
end

Car.instance_methods(false) # => [:engine, :engine=]

通过上述代码,您仅定义了def engine; @engine ;enddef engine=(engine) ;@engine = engine ;end


7

attr_accessor :engine 允许您读取和编写变量 @engine 的值。

attr_reader :engine 只允许您读取变量 @engine 的值。

self.engine = engine@engine = engine 基本上是一样的。


2

它们并不相同

用代码解释:

car = Car.new('cool engine')

对于attr reader,你只能读取

car.engine 
# cool engine

但是你无法做到

car.engine = 'even cool engine'

使用attr_accessor,你可以进行读写操作

car.engine
# cool engine
car.engine = 'even cool engine'
car.engine
# even cool engine

对于实例变量

如果您不想将其暴露给外部世界,请仅使用实例变量。

class Car
  # You don't need to use attr_reader and attr_accessor here if you don't want to expose them to outside world
  def initialize(engine)
    @engine = engine
  end
end

0

不,它们不是相同的。

在第一个示例中,您定义了一个方法engine=,并在initialize内调用该方法。例如,这将允许Car的子类覆盖engine=以执行特定操作,当您调用initialize时,方法调用将被分派到那个被覆盖的方法。这允许子类扩展Car的行为,而无需了解其内部表示形式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接