4

我几乎从未在 Ruby 代码中看到过这一点,但它似乎是有效的:

class Foo
  @bar = "bar"

  def self.print_bar
    puts @bar
  end
end

我对上述内容的解释@bar是 的实例变量Foo,它是 的单例 (?) 实例Class

这似乎与在类范围和实例范围内都可以访问的类变量(例如, )不同。@@baz

如果有的话,像上面的代码片段这样的代码有什么缺点?或者它是完全合理的代码?

4

4 回答 4

6

是的,这是完全有效的。它也被广泛使用,通常推荐用于具有非常大范围的类变量(类、类的所有实例、所有子类、所有子类的所有实例……)。

没有缺点。类是对象。对象可以有实例变量。没什么。Ruby 的对象模型确实比人们想要相信的简单得多,即使是 Ruby 教程的作者也会让你相信。

于 2013-02-05T20:01:13.377 回答
3

一个潜在的缺点是它@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
于 2013-02-05T19:39:59.523 回答
2

代码有效。您正在使用类实例变量。正如 Jörg 所说,它们通常比类变量更受欢迎。它们都可以实现相同的目的,但是类变量有一些陷阱。有关类变量与类实例变量的优缺点,请参阅 Ruby 中的类和实例变量

使用类实例变量的一个缺点是它们看起来与“普通”实例变量相同。这会让新的 Ruby 程序员措手不及。下面的self.print_barandprint_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

在我看来这不是一个很大的缺点,但你问了:)

类实例变量对子类不可用这一事实不一定是不利的。这完全取决于您希望程序的行为方式。

于 2013-02-06T00:55:43.513 回答
1

未初始化的实例变量将有一个nil值,而未初始化的类变量将抛出错误。正如其他人所补充的,类变量可用于子类。

这是一个链接,讨论了我发现有帮助的两个:

http://www.railstips.org/blog/archives/2006/11/18/class-and-instance-variables-in-ruby/

于 2013-02-05T19:51:29.977 回答