2010-09-27 195 views

回答

132

類變量(@@)在該類及其所有後代中共享。類實例變量(@)不被類的後代共享。


類變量(@@

讓我們有一個類Foo有一個類變量@@i和存取方法進行讀取和寫入@@i

class Foo 

    @@i = 1 

    def self.i 
    @@i 
    end 

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

end 

而派生類:

class Bar < Foo 
end 

我們看到,Foo和酒吧有@@i相同的值:

p Foo.i # => 1 
p Bar.i # => 1 

和不斷變化的@@i在一個改變它在兩個:

Bar.i = 2 
p Foo.i # => 2 
p Bar.i # => 2 

類實例變量(@

讓我們用一個類實例va做一個簡單的類可變結構@i和存取讀取和寫入@i

class Foo 

    @i = 1 

    def self.i 
    @i 
    end 

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

end 

而派生類:

class Bar < Foo 
end 

我們看到,雖然酒吧繼承了@i訪問器,它不繼承@i本身:

p Foo.i # => 1 
p Bar.i # => nil 

我們可以設置Bar的@i而不影響Foo的@i

Bar.i = 2 
p Foo.i # => 1 
p Bar.i # => 2 
+0

爲什麼使用類方法返回實例變量? 你經常遇到這種情況嗎? – sekmo 2017-05-13 10:25:21

+0

@sekmo這些示例中的訪問器返回屬於類的_class實例變量_或屬於類層次結構的_class variables_。它們不會返回屬於該類實例的純_實例變量_。術語「實例變量」,「類實例變量」和「類變量」相當混亂,不是嗎? – 2017-05-13 16:03:32

59

首先,你必須明白,類實例太 - 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實例變量是對Hello

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!" 

在另一方面甲類變量一個實例完全無關的且不同於一個實例變量是一種以上兩者的組合,因爲它可通過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,因爲上面的奇怪的行爲,並建議使用class instance variables代替。

+0

+1用於概述這些類是「Class」的實例。 – mikezter 2010-09-27 15:15:45

+1

+1超級解釋!這是每個Ruby新手程序員都應該消化的東西。 – TomZ 2011-11-11 15:08:37