我几乎从未在 Ruby 代码中看到过这一点,但它似乎是有效的:
class Foo
@bar = "bar"
def self.print_bar
puts @bar
end
end
我对上述内容的解释@bar
是 的实例变量Foo
,它是 的单例 (?) 实例Class
。
这似乎与在类范围和实例范围内都可以访问的类变量(例如, )不同。@@baz
如果有的话,像上面的代码片段这样的代码有什么缺点?或者它是完全合理的代码?
我几乎从未在 Ruby 代码中看到过这一点,但它似乎是有效的:
class Foo
@bar = "bar"
def self.print_bar
puts @bar
end
end
我对上述内容的解释@bar
是 的实例变量Foo
,它是 的单例 (?) 实例Class
。
这似乎与在类范围和实例范围内都可以访问的类变量(例如, )不同。@@baz
如果有的话,像上面的代码片段这样的代码有什么缺点?或者它是完全合理的代码?
是的,这是完全有效的。它也被广泛使用,通常推荐用于具有非常大范围的类变量(类、类的所有实例、所有子类、所有子类的所有实例……)。
没有缺点。类是对象。对象可以有实例变量。没什么。Ruby 的对象模型确实比人们想要相信的要简单得多,即使是 Ruby 教程的作者也会让你相信。
一个潜在的缺点是它@bar
不适用于Foo
.
class Parent
@bar = 3
def self.print_bar
puts @bar # nil
end
end
class Child < Parent
end
Parent.print_bar # 3
Child.print_bar # nil
代码有效。您正在使用类实例变量。正如 Jörg 所说,它们通常比类变量更受欢迎。它们都可以实现相同的目的,但是类变量有一些陷阱。有关类变量与类实例变量的优缺点,请参阅 Ruby 中的类和实例变量。
使用类实例变量的一个缺点是它们看起来与“普通”实例变量相同。这会让新的 Ruby 程序员措手不及。下面的self.print_bar
andprint_bar
方法指向不同的 @bar 实例变量。
class Foo
@bar = "bar"
def initialize
@bar = "foo"
end
def self.print_bar
puts @bar #=> "bar"
end
def print_bar
puts @bar #=> "foo"
end
end
在我看来这不是一个很大的缺点,但你问了:)
类实例变量对子类不可用这一事实不一定是不利的。这完全取决于您希望程序的行为方式。
未初始化的实例变量将有一个nil
值,而未初始化的类变量将抛出错误。正如其他人所补充的,类变量可用于子类。
这是一个链接,讨论了我发现有帮助的两个:
http://www.railstips.org/blog/archives/2006/11/18/class-and-instance-variables-in-ruby/