2.8 KiB
2.8 KiB
语法与块:读懂一段 Smalltalk
原书依据:第 4 章,印刷页 13–20,PDF 页 24–31。赋值和返回符号按导读约定规范化。
先识别字面量
| 写法 | 含义 |
|---|---|
42、16rFF、2.5 |
整数、十六进制整数、浮点数 |
$A |
字符 |
'Ada' |
字符串 |
'it''s' |
包含单引号的字符串 |
#size、#at:put: |
符号,常用于表示选择子 |
#(2 4 6) |
字面量数组 |
| `[ :x | x + 1 ]` |
nil、true、false、self、super 是具有特殊语义的伪变量,不能按普通局部变量赋值。不要把字符串 'size' 与符号 #size 混用。
三种消息与优先级
一元消息没有参数;二元消息接受一个参数;关键词消息通过带冒号的片段标出参数位置。at:put: 是一个选择子。
优先级为:括号内表达式 → 一元消息 → 二元消息 → 关键词消息。同级按从左到右处理,二元选择子没有传统乘除优先的规则。
2 + 3 * 4 "推演为 20"
2 + (3 * 4) "推演为 14"
10 raisedTo: 2 + 3 "等价于 10 raisedTo: (2 + 3)"
a at: 1 put: 9 是一条消息。两个关键词调用连续出现时,用括号明确哪一个结果作为另一个的参数。
句点与分号
句点分隔表达式;分号让消息继续发给同一个接收者。
| values |
values := OrderedCollection new.
values add: 4; add: 9; add: 16.
values size
这里三次 add: 的接收者都是 values。若要在一段级联表达式末尾取得集合本身,可发送 yourself:
OrderedCollection new
add: 4;
add: 9;
yourself
块把计算推迟
| square |
square := [ :n | n * n ].
square value: 6
创建块不执行块体;value: 传入参数并求值,预期结果是 36。无参数块接收 value,两个参数可用 value:value:。
控制流也可以用消息与块组织:
| count total |
count := 1.
total := 0.
[count <= 4] whileTrue: [
total := total + count.
count := count + 1].
total
推演结果为 10。条件块每轮重新求值;把条件提前算成单个布尔对象,会失去更新后的判断。ifTrue:ifFalse: 则把两段待执行的分支交给布尔对象选择。
返回的边界
块通常返回最后一个表达式的值。方法若没有 ^ 显式返回,则默认返回接收者。块中的 ^ 涉及从其所属方法返回,不能简单理解成普通函数局部 return。本文示例避免把含非局部返回的块保存到方法退出之后;需要这样的用法时,应核对目标镜像的块实现。
练习:3 + 4 factorial 先执行哪条消息?先向 4 发送 factorial,再向 3 发送 +;按数学结果推演为 27。