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

82 lines
2.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 语法与块:读懂一段 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:` 是一个选择子。
优先级为:**括号内表达式 → 一元消息 → 二元消息 → 关键词消息**。同级按从左到右处理,二元选择子没有传统乘除优先的规则。
```smalltalk
2 + 3 * 4 "推演为 20"
2 + (3 * 4) "推演为 14"
10 raisedTo: 2 + 3 "等价于 10 raisedTo: (2 + 3)"
```
`a at: 1 put: 9` 是一条消息。两个关键词调用连续出现时,用括号明确哪一个结果作为另一个的参数。
## 句点与分号
句点分隔表达式;分号让消息继续发给同一个接收者。
```smalltalk
| values |
values := OrderedCollection new.
values add: 4; add: 9; add: 16.
values size
```
这里三次 `add:` 的接收者都是 `values`。若要在一段级联表达式末尾取得集合本身,可发送 `yourself`:
```smalltalk
OrderedCollection new
add: 4;
add: 9;
yourself
```
## 块把计算推迟
```smalltalk
| square |
square := [ :n | n * n ].
square value: 6
```
创建块不执行块体;`value:` 传入参数并求值,预期结果是 36。无参数块接收 `value`,两个参数可用 `value:value:`。
控制流也可以用消息与块组织:
```smalltalk
| 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。