类variables和类实例variables之间的区别?
任何人都可以告诉我有关类variables和类实例variables之间的区别吗?
类variables( @@
)在类和它的所有后代之间共享。 类实例variables( @
)不是由类的后代共享的。
类variables( @@
)
让我们有一个类variables@@i
的类Foo,以及用于读写@@i
:
class Foo @@i = 1 def self.i @@i end def self.i=(value) @@i = value end end
和派生类:
class Bar < Foo end
我们看到Foo和Bar对@@i
具有相同的值:
p Foo.i # => 1 p Bar.i # => 1
而改变@@i
在一个改变它在两个:
Bar.i = 2 p Foo.i # => 2 p Bar.i # => 2
类实例variables( @
)
让我们用一个类实例variables@i
创build一个简单的类,然后使用访问器读取和写入@i
:
class Foo @i = 1 def self.i @i end def self.i=(value) @i = value end end
和派生类:
class Bar < Foo end
我们看到,尽pipeBarinheritance了@i
的访问器,但它并不inheritance@i
本身:
p Foo.i # => 1 p Bar.i # => nil
我们可以设置Bar的@i
而不影响Foo的@i
:
Bar.i = 2 p Foo.i # => 1 p Bar.i # => 2
首先,您必须了解类也是实例 – Class
类的实例。
一旦你理解了,你可以理解一个类可以有一个与它相关的实例variables,就像一个普通的(read:non-class)对象一样。
Hello = Class.new # setting an instance variable on the Hello class Hello.instance_variable_set(:@var, "good morning!") # getting an instance variable on the Hello class Hello.instance_variable_get(:@var) #=> "good morning!"
请注意, Hello
上的实例variables与Hello
实例上的实例variables完全无关,并且与其不同
hello = Hello.new # setting an instance variable on an instance of Hello hello.instance_variable_set(:@var, :"bad evening!") # getting an instance variable on an instance of Hello hello.instance_variable_get(:@var) #=> "bad evening!") # see that it's distinct from @var on Hello Hello.instance_variable_get(:@var) #=> "good morning!"
另一方面, 类variables是上述两种types的组合,因为它可以在Hello
本身及其实例上访问,也可以在Hello
及其实例的子类上访问:
HelloChild = Class.new(Hello) Hello.class_variable_set(:@@class_var, "strange day!") hello = Hello.new hello_child = HelloChild.new Hello.class_variable_get(:@@class_var) #=> "strange day!" HelloChild.class_variable_get(:@@class_var) #=> "strange day!" hello.singleton_class.class_variable_get(:@@class_var) #=> "strange day!" hello_child.singleton_class.class_variable_get(:@@class_Var) #=> "strange day!"
很多人说因为上面的奇怪的行为而避免class variables
,build议使用class instance variables
。