跳转到内容

软件工程师手册/语言词典/Smalltalk

来自维基教科书,开放的书籍,开放的世界

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 年。

华夏公益教科书