類別級別上定義的類別變量和變量之間有什麼區別?類別級別定義的類別變量和變量之間的區別是什麼
說吧,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
區別在於你的陳述是錯誤的。你試過了嗎? –