Files
endorphin-tabularium-docs/content/docs/smalltalk/02-syntax-and-blocks.md
T

2.8 KiB
Raw Blame History

语法与块:读懂一段 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。