Smalltalk变量:我为什么要声明它们?

eva*_*a02 3 smalltalk gnu-smalltalk

基本上我可以通过为它们分配一些东西来使用变量,例如:

x := something
Run Code Online (Sandbox Code Playgroud)

它工作正常.

但是在类中,如果我定义一个新方法,但是我没有声明变量,我得到一个"赋值给未声明的变量x",所以我必须使用:

|x| x := something
Run Code Online (Sandbox Code Playgroud)

为什么是这样?

Lea*_*lia 6

正如Uko所提到的,Smalltalk中存在不同类型的变量,这就是我们需要以不同方式声明它们的原因.为了完整起见,我们在这里查看所有Smalltalk变量.


1.实例变量

含义:这些是定义类形状的.例如,该类Point定义了ivars xy.

声明:在类定义中.

范围:本地,仅限于每个实例.

案例:通常是小写的.

2.类变量

含义:这些变量在多个对象之间共享.但它们不是全球性的.

声明:在类定义中.

范围:由类,其元类,所有子类,其元类,所有实例和所有子实例共享.

案例:通常是大写.

3. 类实例变量

含义:是元类的实例变量,因此决定了类的形状(而不是其实例).

声明:在类定义中.

范围:本地,仅限于类方法.

案例:通常是小写的.

4. 临时工

含义:这些是方法和块中使用的辅助变量.每次激活方法时,它们都会在执行堆栈中分配(期望在方法或块闭包中声明并在内部块中使用).

声明:| temp |方法的(或块)主体的开头处的管道之间.

范围:激活方法或块.

案例:通常是小写的.

5. 池变量

含义:保存在全局中PoolDictionaries,可以在任何声明其使用的类中使用.

声明:该类声明了PoolDictionary定义它们的用法.

范围:类和所有子类和元类.

案例:通常是大写.

6. 全局变量

含义:由系统中的每个对象共享.

宣称:无处可去.它们在Smalltalk系统字典中通过meas来定义Smalltalk at: <GlobalSymbol> put: <an object>.声明后,可以使用更改它们的值:=.

范围:整个图像.

案例:通常是大写.

备注:类名是全局变量.但是,您不应该使用它们:=(除非您知道自己在做什么.)

7. 伪变量

含义:可以通过不写入来阅读它们.它们是:self,super,true,falsenil.

宣称:无处可去.

适用范围:可随处使用.但是,使用它们的对象的含义selfsupper更改.

8.方法和块参数

含义:它们表示方法或块在每次激活时将接受(和要求)的正式参数.

声明:在方法签名或块的开头.

范围:声明它们的方法或块.

案例:小写.

9.工作区变量

含义:这些是与工作空间相关的变量(Pharo中的Playground).

声明:通常不显式声明(工作空间将在幕后声明它们).

范围:工作空间的生命.

案例:小写.

  • 对于刚开始使用Smalltalk的人来说,这是非常好的信息.但是......它实际上并没有回答这个问题(为什么要宣布?).如果您要问一个新问题,比如"Smalltalk中有哪些类型的变量?" 并将这个答案移到那里,我会同时投票.;-)哦,我可能会补充说,通过执行`Smalltalk at:#GlobalName put:value`可以"定义"(好吧,添加)全局变量.想想看,这种事情在[Smalltalk文档](http://stackoverflow.com/documentation/smalltalk/topics)中更为合适,这仍然非常稀疏. (4认同)

Uko*_*Uko 5

x := something允许出于脚本原因.实际上,它x为您的脚本创建了一个变量.现在,如果您x在没有显式声明的方法中编写,应该创建哪种变量?临时变量,实例变量,类变量,池变量,还是全局绑定?要避免此类问题,您必须在某处声明变量然后使用它.

不同的其他语言使用另一种策略,例如,@@如果变量必须是类变量,则为变量添加前缀.但是这会引入难看的语法,限制你的命名自由等等......