类别级别上定义的类别变量和变量之间有什么区别?类别级别定义的类别变量和变量之间的区别是什么
说吧,bar定义为@@
这意味着它是一个类变量,并且可以在类中的所有方法中访问。
class Foo
@@bar = 'bar'
end
也是如此bar
无@@
,所以有什么区别..?
class Foo
bar = 'bar'
end
类别级别上定义的类别变量和变量之间有什么区别?类别级别定义的类别变量和变量之间的区别是什么
说吧,bar定义为@@
这意味着它是一个类变量,并且可以在类中的所有方法中访问。
class Foo
@@bar = 'bar'
end
也是如此bar
无@@
,所以有什么区别..?
class Foo
bar = 'bar'
end
好吧,你的第二个选项,bar
是一个局部变量达到end
时失控的范围。因此,它不会被类的任何方法(类方法或实例方法)访问。在Ruby中,有一些类变量(@@bar
,它们在所有子类及其实例和实例变量之间共享)(@bar
)由于类也只是Ruby中的对象,因此您还可以定义一个实例变量在类级别(或更正确:在单类类的),这能像这样工作:
class Foo
def self.bar
@bar
end
def self.bar=(value)
@bar = value
end
end
相比于类变量,在单件类,这些实例变量不在Foo
情况下,也没有上访问子类为Foo
。
@@bar
将向该类的所有实例返回相同的变量,而不仅仅是类中所有方法的相同变量。
我认为类变量(@@变量)的方式是命名空间的全局变量。它们的用法与使用全局变量差不多,但并不完全是因为您将范围限制在您的类中定义的代码内。
通常它们将用于跟踪应用程序中的某种状态。
假设您有一个对象需要能够识别其最近实例化的同级对象。 一种方式做到这一点是通过一个全局变量:
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_thing = :something_else
他们可以使用的方式已被全局使用。
希望有所帮助。我认为类变量很少在野外使用或鼓励,但在罕见的情况下,我需要使用它,这是为了这样的事情。
实践中,全局实际上是非常糟糕的,它们的范围太广泛了,但是班级变量紧随其后。 99%的时间你需要的是一个类级别的方法,可以为你介绍这一点,比如'self.class.latest_thing = self',这是一种方法。然后,班级本身可以自由解释,但它看起来合适。 – tadman
区别在于你的陈述是错误的。你试过了吗? –