Ruby 类变量和在类级别定义的变量之间有什么区别

Ruby 类变量和在类级别定义的变量之间有什么区别,ruby,oop,Ruby,Oop,类变量和在类级别定义的变量之间有什么区别 比如说,bar是用@定义的,这意味着它是一个类变量,可以在类中的所有方法中访问 class Foo @@bar = 'bar' end 没有@的条码也是如此,那么区别是什么呢 class Foo bar = 'bar' end 好的,在第二个选项中,bar是一个局部变量,当到达末尾时超出范围。因此,该类的任何方法(类方法或实例方法)都无法访问它 话虽如此,在Ruby中,所有子类及其实例和实例变量(@bar)之间共享类变量(@bar),因为类在

类变量和在类级别定义的变量之间有什么区别

比如说,bar是用
@
定义的,这意味着它是一个类变量,可以在类中的所有方法中访问

class Foo
  @@bar = 'bar'
end
没有
@
条码也是如此,那么区别是什么呢

class Foo
  bar = 'bar'
end

好的,在第二个选项中,
bar
是一个局部变量,当到达
末尾时超出范围。因此,该类的任何方法(类方法或实例方法)都无法访问它

话虽如此,在Ruby中,所有子类及其实例和实例变量(
@bar
)之间共享类变量(
@bar
),因为类在Ruby中也只是对象,所以您还可以在类级别上定义实例变量(或者更准确地说,在类的单例类上)。这可以像这样工作:

class Foo
  def self.bar
    @bar
  end

  def self.bar=(value)
    @bar = value
  end
end

与类变量相比,singleton类上的这些实例变量在
Foo
实例和
Foo
的子类上都是不可访问的,
@@bar
将向类的所有实例返回相同的变量,而不仅仅是向类中的所有方法返回相同的变量

我认为类变量(@@variables)是有名称空间的全局变量。它们的用法与使用全局变量一样令人不快,但这并不完全是因为您将作用域限制在类中定义的代码内

通常,它们将用于跟踪应用程序中的某种状态

假设您有一个需要能够识别其最近实例化的同级对象的对象。 一种方法是通过全局变量:

class MyThing
  def initialize
    $latest_thing = self
  end

  def latest
    $latest_thing
  end
end

thing1 = MyThing.new
thing1.latest         # => thing1
thing2 = MyThing.new
thing1.latest         # => thing2
thing2.latest         # => thing2
现在,它使用了一个全局变量,这通常被认为是不好的做法,原因之一是全局名称空间受到污染,并且存在命名冲突和/或其他人更改它的风险

如果您正在处理这样一种情况,即您需要实例之间的共享状态,但外部没有人需要知道它,那么您可以像使用全局变量一样使用类变量:

class MyThing
  def initialize
    @@latest_thing = self
  end

  def latest
    @@latest_thing
  end
end

thing1 = MyThing.new
thing1.latest         # => thing1
thing2 = MyThing.new
thing1.latest         # => thing2
thing2.latest         # => thing2
这通常是更干净/更安全/更好的封装,因为任何第三方代码都不能简单地执行
@@latest\u thing=:如果使用全局代码,它们可以执行的其他操作


希望这能有所帮助。我认为在野外很少使用或鼓励使用类变量,但在这样的情况下,我很少需要使用类变量。

不同的是,你的说法是错误的。你尝试过吗?全局变量在实践中非常糟糕,它们的范围太广,但类级变量紧随其后。99%的时间里,你需要的是一个类级方法,它可以为你提供中介,比如
self.class.latest\u thing=self
,它是一个方法。然后,类本身可以自由地解释它,不管它认为合适。