
来源
四人帮成员之一拉尔夫·约翰逊(Ralph Johnson)曾经展示过Smalltalk-80语言的语法如何适合明信片。 现在,距Smalltalk的第一个版本已经将近30年了,发展最快的Smalltalk方言就是Pharo,我们稍后会介绍。
方法声明
exampleWithNumber: x
方法被声明为:
并且是该类的成员。 这样声明具有多个参数的方法
rangeFrom: start to: end
方法名称为rangeFrom:to:
,参数名称为start
和end
。
语用宣言
<syntaxOn: #postcard>
注释用于注释该方法。 编译器或其他方法可以将此注释用作元数据。
留言
注释用引号引起来。 注释内的引号由双引号指示。
声明局部变量
| y |
局部变量用于方法内部的计算中。 由于Smalltalk是动态类型化的语言,因此不需要变量类型声明。
在一个列表中声明了几个变量。
| yx totalSum |
对象和消息
true & false not & (nil isNil)
Smalltalk中的所有内容都是一个对象,对象可以接收消息。 执行顺序(即发送消息)从左到右,但是不带参数的消息主要根据优先级规则发送,因此此处的计算顺序为
(true & (false not)) & (nil isNil)
Smalltalk中只有四个优先级规则:首先,消息在括号中发送,然后是一元消息(除了接收者对象本身之外没有其他参数,例如false not
),然后是二进制消息(带有一个其他参数,例如1 + 2
),然后是带有几个参数(例如15 between: 1 and: 2
)。 执行的优先级由一个简单的方案表示。
括号 > 一元 > 二进制 > 具有多个参数的消息
这些规则也适用于数学运算,因此表达式的结果
1 + 15 / 4
将是4
。 顺便说一句, nil
也是一个对象,可以接收和响应消息。
条件执行和代码块
true & false not & (nil isNil) ifFalse: [ self perform: #add: with: x ].
通过将ifTrue
和ifFalse
消息发送到ifFalse
对象来实现条件执行。 该消息的参数是一个代码块,由方括号表示,如果满足指定条件,则执行该代码块。
Smalltalk块还用作匿名函数:
sum := [ :x :y | x+y ]. sum value: 10 value: 25.
向自己发送消息
self perform: #add: with: x
在向对象本身发送消息时, self
关键字用作包含该方法的对象的引用。 在这里,我们发送一个#add
:with:消息,其中包含#add
和x
参数。 符号#
表示文字字符串,在此用作方法标识符。
变量分配
y := thisContext stack size + super size.
分配变量由运算符:=
指示。 super关键字用于引用超类对象。
所有Smalltalk对象都从Object
类或其父类继承,而后者又从其超类或Object
类继承。
静态数组
byteArray := #[2 2r100 8r20 16rFF].
byteArray
是在声明类时声明的类实例变量。 byteArray数组由以不同形式写在不同数字系统中的整数组成
<>r<>
静态数组的大小是固定的,并在编译时设置。 数组索引从1开始
byteArray at: 2
从一开始,Smalltalk不仅是一种语言,而且是具有自己的虚拟机的集成开发环境:Smalltalk类和方法不存储在单独的文本文件中,而是立即保存在虚拟机映像中并通过开发环境接口声明。 例如,类Counter
在类部分中声明为
Object subclass: #Counter instanceVariableNames: 'count initialValue' classVariableNames: '' package: 'MyCounter'
及其方法在Counter
类的方法部分中声明。
动态数组
{ -42 . #($a #a #'I''m' 'a' 1.0 1.23e2 3.14s2 1) }
动态数组在运行时创建。
数组可以包含不同类型的数据:数组的第一个元素是数字-42,数组的第二个元素是具有不同类型的元素的数组:
$a
a-字符“ a”#a #'I''m'
文字字符串“ a”和“ I'm”'a'
a'-字符串“ a”1.0 1.23e2
浮点数3.14s2
比例为2的小数部分
周期数
{ -42 . #($a #a #'I''m' 'a' 1.0 1.23e2 3.14s2 1) } do: [ :each | | var | var := Transcript show: each class name; show: each printString ].
通过将消息发送到带有将在该数组的每个元素上执行的块的数组来实现Smalltalk中的循环,这与功能方法非常相似。 在每次迭代时,将数组的元素作为参数传递给对它执行一些计算的块。 在示例的块中,声明了局部变量var,该变量被分配了将最后一个显示消息发送到全局Transcript
对象的结果。
Smalltalk的一个有趣功能是能够级联消息:表达式
Transcript show: 'A'; show: 'B'.
在“ Transcript
控制台窗口中顺序显示A
和B
行。 这相当于代码
Transcript show: 'A'. Transcript show: 'B'.
但要避免重复Transcript消息接收者对象的名称。 级联的结果是对象对最后一条消息的响应。
从方法返回值
^ x < y
返回由^
表示。 在这种情况下,将返回逻辑值-比较结果x < y
。