我从 this tutorial 中看到了以下示例:
class Song
@@plays = 0
def initialize(name, artist, duration)
@name = name
@artist = artist
@duration = duration
@plays = 0
end
def play
@plays += 1
@@plays += 1
"This song: #@plays plays. Total #@@plays plays."
end
end
s1 = Song.new("Song1", "Artist1", 234) # test songs
s2 = Song.new("Song2", "Artist2", 345)
puts s1.play
puts s2.play
puts s1.play
puts s1.play
@@plays 是否只能在 Song 类中礼貌地访问? This commentary提出了不推荐使用类变量的观点。是不是因为它们在日常使用中通常不是必需的,并且在使用时会产生很多令人头疼的调试问题?
最佳答案
类变量从来都不是真正需要的。但原因并不是它们是共享状态。我的意思是,尽可能避免共享状态是件好事,但这不是这里的真正问题。
他们被反对的原因是,如那篇文章所示,他们真的很困惑。特别是,一个类的类变量由它的子类和它的子类的实例共享。例如:
class Parent
end
class Child1 < Parent
@@class_var = "Child1's"
end
class Child2 < Parent
@@class_var = "Child2's"
end
使用这段代码,Child1 及其实例都将看到名为 @@class_var
且值为 "Child1's"
的类变量,而 Child2 及其实例将看到一个名为 @@class_var
的类变量,值为 "Child2's"
。但是假设稍后我们重新打开 Parent 并写下:
class Parent
@@class_var = "Parent's"
end
现在 Parent 及其创建的实例都将看到一个名为 @@class_var
的类变量,其值为 "Parent's"
。 但这还不是全部。现在父类有了这个变量,Child1 和 Child2 突然共享了这个变量,所以所有的 @@class_var
都有值 "Parent's"
。如果您重新分配 Child1 中的变量,它仍然是共享的,因此所有类都会更新。多么困惑!
你可以只使用类的实例变量而不是类变量,如下所示:
class Parent
@class_var = "Parent's"
def self.class_var
@class_var
end
end
class Child1 < Parent
@class_var = "Child1's"
end
class Child2 < Parent
@class_var = "Child2's"
end
现在,Parent.class_var
将返回“Parent's”,Child1.class_var
将返回“Child1's”,Child2.class_var
将返回“Child2's”——正如您所期望的那样。
关于ruby - Ruby 中的类变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10594444/