[英]Where are class variables defined in Smalltalk?
我想知道,如果我定義一個新的 class 變量,例如對於 class MyClass
,定義是在MyClass
還是MyClass class
? MyClass class
是否知道新的 class 變量?
是的,class 變量與 class 和元類共享。 它們還與所有子類(及其元類)共享。 class 變量通常大寫,以更好地傳達在比 class 更廣泛的 scope 中共享的想法。 您在 class(不是元類)中定義 class 變量。
Class 變量不應與 class 實例變量混淆,后者是在元類級別定義的實例變量,即 class ZA8ZCFDE6331BD4B866AC 的實例變量盡管這個概念很簡單(或正因為如此),但這個概念有些模糊:實例變量總是在 class 中定義,以定義其實例的形狀(插槽) 。 因此,如果我們將此定義應用於元類,即 class 的 class,則此處定義的實例變量定義其實例的形狀,其中(通常)只有一個,ZA2F2ED4F8EBC2CBB4C21A29DC40AB6D
回到 class 變量,您在 class(inst 端)中定義它們並在元類(即 class 端)中初始化它們。 請記住,從某種意義上說,這些是(部分)全局變量,將在實例、子實例、子類和元類之間共享,因此必須像對待全局變量一樣小心處理它們。
再澄清一件事
當我們說實例變量在實例和子實例之間共享時,我們指的是它們的名稱(以及在 object 插槽的 memory 中的位置); 我們不是指它們的值(所述插槽的內容)。 因此,如果 class 定義了 ivar color
,則 class C
的兩個實例將共享名稱,例如color
,但它們在每個實例中的值將是獨立的。 換句話說,它共享的是名稱,而不是值。
對於 class 變量,共享的是名稱和值。 其實就是Association
object,比如Theme -> aTheme
,分享的是什么。 因此,對 class 變量值的任何修改都會影響其所有引用。 class 實例變量不是這種情況,因為它們只是實例變量,除了它們塑造 class 及其子類,而不是常規實例和子實例。
有關 Smalltalk 變量的更多信息,請參閱https://stackoverflow.com/a/42460583/4081336
作為對 Leandro 答案的補充,這里是主要的 Squeak 實現特定方法,它解釋了在實例端(類)和 class 端(元類)之間共享 class 變量:
Metaclass>>classPool
"Answer the dictionary of class variables."
^thisClass classPool
其中thisClass
是元類的唯一實例,即 class 本身...
盡管在大多數 Smalltalk 方言中找到類似實現的可能性很大。
編譯器將首先嘗試將變量解析為方法/塊臨時(包括方法/塊參數),然后是實例變量,然后是共享變量。
classPool 方法由編譯器在最后階段發送。
Leandro 確實解釋過,編譯器要么將綁定解析為在實例變量插槽或方法臨時變量的情況下將直接轉錄到字節碼中的偏移量,要么作為共享變量情況下的一種關聯,這種關聯通常是添加到 CompiledMethod 文字並在處理此變量的所有方法之間有效共享(所有方法都指向有效共享的相同 Assocation object)。
編譯器部分更加特定於方言,在 Squeak 中,正是這種方法用於解析共享變量的綁定:
class>>bindingOf: varName environment: anEnvironment
"Answer the binding of some variable resolved in the scope of the receiver"
| aSymbol binding |
aSymbol := varName asSymbol.
"First look in local classVar dictionary."
binding := self classPool bindingOf: aSymbol.
binding ifNotNil:[^binding].
"Next look in local shared pools."
self sharedPools do:[:pool |
binding := pool bindingOf: aSymbol.
binding ifNotNil:[^binding].
].
"Next look into superclass pools"
superclass ifNotNil: [^ superclass bindingOf: aSymbol environment: anEnvironment].
"No more superclass... Last look in declared environment."
^anEnvironment bindingOf: aSymbol
這是為了提醒您,Smalltalk 最有趣的部分之一是您可以從 IDE 中深入研究實現,Smalltalk 本質上是用 Smalltalk 編寫的!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.