软件工程师手册/语言词典/Smalltalk
以下是 维基百科条目.
Smalltalk 是一种完整的过程式面向对象语言。
所有参数在概念上都是对对象的引用。然而,所有实现都将小整数表示在指针中,而不是为每个整数分配物理对象。
该语言不要求实现支持正确的尾递归,而且没有任何实现支持。
正是与 Smalltalk 的联系使“面向对象”一词首次出现,尽管第一种面向对象语言是 Simula 67。
Smalltalk 程序通常没有单个入口点,而是保存为映像文件(对象内存快照)。启动后,这些映像文件将继续执行在保存时所执行的操作。
Smalltalk 表达式由消息发送和变量赋值组成。
a := b := c + 2 * (x even ifTrue: [y] ifFalse: [z negated]).
消息发送可以是以下几种:
- 一元(在上面的示例中:even,negated)
- 二元(+,-,等等)
- 关键字(ifTrue:ifFalse:)
一元消息绑定最强,然后是二元消息,最后是关键字消息。二元消息从左到右进行评估,没有运算符优先级。赋值从右到左进行评估。消息表达式可以加括号。方括号 [] 表示代码块。代码块是一级对象,可以作为参数进行赋值和传递。
Smalltalk 注释以双引号字符分隔
"This is a comment"
它们可以跨越多行。
变量必须声明,但它们没有类型信息。方法参数通常在名称中包含其预期作用或预期类。
临时变量
| x y total subtotal |
方法参数
addAmount: aDecimalNumber purpose: aString
代码块参数
[:a :b | a < b]
代码块执行
[:a :b | a < b] value:1 value: 2
实例变量和类变量是在类定义消息中声明的(不同实现之间的细节有所不同)
Object subclass: #MyClass instanceVariableNames: 'name owner additionalData' classVariableNames: 'DataRepository'
静态作用域变量(全局变量和类变量)通过执行创建它们的表达式来声明。例如,类定义消息。
程序员在类上编写方法。类是对象可以作为实例制作的柏拉图模式。在 Smalltalk 中,每个类也被实现为一个对象,支持创建和返回新实例(new)的协议。类具有全局名称;所有全局名称都以大写字母开头。
注意,编程语言 Self 继承了 Smalltalk 的许多优点,但通过消除类的概念,在概念上更简单。
Smalltalk 具有全局变量、实例变量、临时变量(对方法)和参数(对方法)。代码块也可以有参数。在大多数现代实现中,代码块也可以有自己的临时变量。还有一种叫做池变量的东西,它们与全局变量的生存期相同,但只有在明确包含池的类(以及这些类的层次结构)中才能访问。
在实践中,池和全局“变量”通常用于常量。
条件语句是普通消息表达式。消息接收者是一个布尔值(true 或 false),而参数是代码块。
a < 10 ifTrue: [self handleSmallValue].
self hasValidInput ifTrue: [self processInput] ifFalse: [self displayInputFormatError]
循环是通过向代码块发送消息来完成的
[stream atEnd] whileFalse: [self process: stream nextLine]
[a < limit] whileTrue: [a := a + 1]
对集合的迭代使用 'do:'
anArray do: [:each | self doSomethingWith: each]
计数循环看起来像这样
1 to: 10 do: [:i | Transcript show: i printString; cr]
由于大多数 Smalltalk 系统不是面向命令行的,因此通常不使用对“stdout”的输出。但是,Smalltalk 系统通常有一个日志窗口(Transcript),可以将输出写入其中
Transcript show: 'Hello, world!'; cr
标准 Smalltalk 库包括大量可变集合类的集合:Array、OrderedCollection(在其中有效地从任一端追加或删除,并且存储经济(作为数组而不是链接列表或树)、Set、Bag、Dictionary、IdentityDictionary、SortedCollection。集合支持有用的二阶函数 collect:(如 Lisp 中的 map)、select:、detect: 和 reject:,以及二阶过程 do:。
由于 Smalltalk 是动态类型的,因此它的容器也是动态类型的;它们可以指向任何类型对象的任意组合。
<列出该语言原生可用的算法或算法列表的引用。列出在该语言不支持的情况下如何合并算法。或者,如果不可用,请描述这一点。>
垃圾回收是自动的。
一些实现支持弱引用。
传统的 Smalltalk-80 系统由以下部分组成:
- 运行时引擎(解释器或 JIT 加上基元和平台接口)
- 映像文件
- 'changes' 文件(源代码和已评估表达式的日志)
- 'sources' 文件(初始映像中方法的源代码)
现代系统通常将运行时引擎分成可执行文件和共享库,并且可能包含用于版本控制系统等的附加文件。
不要过分执着于你的旧习惯。你可以在 Smalltalk 中编写 Pascal 风格的程序,但它们不会是好的 Smalltalk 程序。
将行为与最相关的对象保持一致。通常将你的对象拟人化,并以第一人称编写注释,例如
addEntry: anEntry "Add anEntry to my list of entries. If the entry conflicts with another entry, I will drop the older one." entries removeAllSuchThat: [:oldEntry | anEntry conflictsWith: oldEntry]. entries add: anEntry
Smalltalk 免费书籍的一个很棒的资源 [1]
<列出可能会有帮助的其他书籍和文章。请包括参考书适合的读者水平。(初级/中级/高级)>
Goldberg 和 Robson
Byte 杂志 Smalltalk 专刊,1979 年。