Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
理解Ruby类实例变量_Ruby - Fatal编程技术网

理解Ruby类实例变量

理解Ruby类实例变量,ruby,Ruby,可能重复: 有人能解释一下以下两者之间的区别吗?为什么不像人们所期望的那样: # 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 en

可能重复:

有人能解释一下以下两者之间的区别吗?为什么不像人们所期望的那样:

# 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
关键字。为什么不能在
初始化
方法中使用此选项?或者你能吗?我试过使用它,但它似乎并没有像预期的那样工作,我只是不知道该使用哪种技术,什么时候,更重要的是为什么


我真的希望有人能帮我一劳永逸地澄清这一点:)你不需要在某种方法中使用self;对于实例变量,应该直接用@赋值,就像在版本1或2中一样。self与Python不同;例如,它用于声明类方法(如C++中的静态函数)。

版本1:构造函数创建两个实例变量,
@name
@age
。这两个变量是私有的(所有Ruby实例变量都是私有的),因此您不能在类之外访问它们

版本2:与#1完全相同,只是您还为这两个变量定义了getter和setter方法。
attr\u accessor
所做的是为每个参数创建两个方法,允许您获取/设置具有相同名称的实例变量的值

版本3:与#2完全相同,只是在构造函数中您没有直接设置实例变量,而是调用
User#name=
User#age=
方法来设置实例变量的值,而不是直接设置它们

为了明确设置实例变量和调用SETER方法之间的区别,请考虑这个例子:

user = User.new "Rob", 26
user.name = "Joe"

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

您能否更具体地说明哪一个失败以及您期望的输出?这与类实例变量有什么关系?self在java中与此相同吗?是的,self是对的引用“本身“像
这样
您是否应该直接分配给实例变量还很模糊。我强烈支持这一点,不要认为你可以说你应该直接分配给它,因为使用setter有很多真正的好处。我认为你能证明它值得直接分配给IVAR的唯一方法是当你没有设置器时(使用attr_reader而不是attr_accessor)。。。我认为直接分配给IVAR在类方法中更有意义,因为IVAR应该是类的实现层的一部分,这是类方法使用的一个层(换句话说,我认为IVAR应该在类方法中引用,原因与它们不应该在类方法之外相同-分离内部,“实现”、“私有”层的类从外部开始,“公共”层)但是,我认识到,在任何给定的上下文中,其中一个在语义上可能比另一个更有意义。在这种情况下,我有时会将
attr\u accessor
放在
private
关键字之后。这更难看,但我得到了使用setter的好处——它们对类的好处不如对实例的好处,因为e类不太可能继承功能,而且因为可变类通常不是一个好主意,因为它们是单例的)