smalltalk 中的变量类型

Variable types in smalltalk

我需要帮助来理解 Smalltalk 中变量的用法和区别。 下面给出的代码中每个变量的区别和用法是什么?

Object subclass: #MyClass
  instanceVariableNames: 'x'
  classVariableNames: 'Yy'
  poolDictionaries: ''
  category: 'helpMe'

MyClass class
  instanceVariableNames: 'zzz'

实例变量 (x) 是实例的局部变量。 class 和任何其他实例都不能访问该变量。

A​​ class 变量 (Yy) 对 class、它的所有实例、所有子 class 和所有子实例(因此整个层次结构)是局部的.任何子class或子实例都可以看到该变量的值。

A​​ class 实例变量 (zzz) 是 class 的局部变量。只有定义变量的 class 可以访问它,实例和子 classes 都不能看到变量(尽管 subclasses 继承了 declaration 的变量,它们的变量将具有不同的值)。 类 也是 Smalltalk 中的对象。因此,您可以像考虑实例变量一样考虑 class 实例变量:没有其他实例(class 的实例)可以看到该值。感谢@Amos M. Carpenter 指出这一点。

变量是标识符。变量包含对某个对象的引用。

instanceVariableNames:此处x属于class.

的一个实例

classVariableNames:这里Yy有一个与所有classes的所有实例共享的变量副本,它可以静态变量。 所以 x 可以在不同的对象中有不同的值。但是 Yy 只能有一个值。

poolDictionaries:在 smallTalk 中创建以提供对一组 classes

之间共享的变量的访问

类别 'helpme' 是相关 class 的集合,如果您创建的 class 没有类别; class 是用空白类别创建的。

subclass有自己的instanceVariableNames(zzz),也有继承属性.

为了避免非小众用户之间的混淆: 你输入的是一条消息(给对象 class),要求它创建一个名为 'MyClass' 的子 class,带有一个实例变量(一个实例私有槽)名为 'x' 和一个名为 'Yy' 的 class 变量。紧随其后的是给刚刚创建的 class 的消息,以定义一个名为 'zzz' 的 class 实例变量(这是 class 对象中的一个槽 - 而不是它的实例中的一个槽)。

  • 全局变量
    'Object'和'MyClass'是"global variables"。这些是可见的 无处不在,在全球词典中具有技术约束力 (持有键值对)。在旧的实现中,只有一个 这样的字典;在最近的实现中,有多个,它们被称为 "namespaces"。在您的示例中,发送到对象 class 的 class-定义消息将为 'MyClass' 名称创建这样一个新绑定。

  • Class变量
    'Yy'是一个class变量; this 也指一个绑定,但该绑定仅在 class 及其子 class 内部可见,对 class 方法和实例方法(见下文)。所有引用相同的绑定,因此 subclasses 将看到相同的值。它们可以在 subclasses 中重新定义,但是再一次,重新定义 subclass 的所有 subclasses 都引用相同的绑定。

  • 实例变量
    这些是对象的私有槽。 'x' 是您示例中的一个。一个对象的布局和方法(操作)被 subclasses 继承,当然,每个单独的实例都有自己的值。实例变量对实例方法可见(当然)。

  • Class实例变量
    因为classes本身就是对象(meta-class的实例),它们可以有私有槽以及。从技术上讲,它们只是 class 对象的实例变量,并且对 class 方法可见。与实例变量一样,布局和方法由 subclasses 继承,但每个 (class) 都有自己的值。这经常被 C++/Java 的人误解,因为他们在他们的语言中没有相应的构造(还要注意 class 方法是继承的并且可以在 Smalltalk 中重新定义,而其他语言中的静态函数不能)

  • 池变量(共享池)
    类似于class变量,因为它们指的是非全局持有的绑定class目的。但是,这些在许多协作 classes 中可见(类似于另一种语言中的 "friends")。通过在 class 定义消息中命名池,它的绑定对 class 和实例方法可见。通常,这些用于定义共享常量。

其他变量类型(不存在于您的代码示例中)是方法局部变量和块局部变量。这些指的是当前上下文中的槽,从技术上讲,它是方法或块(或外部上下文,如果块实际上是闭包)的堆栈框架(延续)。

'category'只是class的一个属性,不要和上面的变量混淆。将其视为附加到它的标签,以允许在浏览器中更好地组织。此属性存储位置的详细信息是特定于方言的:大多数使用单独的(所谓的 "organization"),这是一个字典。但是,至少有一种方言(ST/X)将其保留为 class 对象的私有槽(并且在某种意义上它确实是一个变量)。