理解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类不太可能继承功能,而且因为可变类通常不是一个好主意,因为它们是单例的)