Ruby 类变量和在类级别定义的变量之间有什么区别
类变量和在类级别定义的变量之间有什么区别 比如说,bar是用Ruby 类变量和在类级别定义的变量之间有什么区别,ruby,oop,Ruby,Oop,类变量和在类级别定义的变量之间有什么区别 比如说,bar是用@定义的,这意味着它是一个类变量,可以在类中的所有方法中访问 class Foo @@bar = 'bar' end 没有@的条码也是如此,那么区别是什么呢 class Foo bar = 'bar' end 好的,在第二个选项中,bar是一个局部变量,当到达末尾时超出范围。因此,该类的任何方法(类方法或实例方法)都无法访问它 话虽如此,在Ruby中,所有子类及其实例和实例变量(@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
,它是一个方法。然后,类本身可以自由地解释它,不管它认为合适。