59 lines
3.3 KiB
Markdown
59 lines
3.3 KiB
Markdown
# 基础类库:数值、集合与流
|
||
|
||
> 原书依据:第 9–12 章,印刷页 53–90,PDF 页 64–101。
|
||
|
||
这些章节适合按“要保存什么、如何比较、如何遍历”阅读。具体消息是否存在仍以书中 Version 2 镜像为范围。
|
||
|
||
## 有序值与数值
|
||
|
||
`Magnitude` 抽象可比较对象;原书讨论其下的 `Date`、`Time`、`Character` 与数值体系。日期和时间章节的构造协议具有历史性,不能直接当作时区或国际化指南。字符章节基于当时的有限字符集合,不能扩展成 Unicode 结论。
|
||
|
||
`Number` 的主要子类包含 `Integer`、`Fraction` 和 `Float`。整数层级还区分小整数与大整数。算术消息的结果可以由不同数值类表示,不能仅根据左操作数认定返回类型。
|
||
|
||
```smalltalk
|
||
1 / 3
|
||
7 // 2
|
||
7 \\ 2
|
||
```
|
||
|
||
在原书数值模型中,第一条可以表示精确分数,后两条分别体现整除和余数协议。这里的余数选择子写作两个反斜杠;使用其他方言时务必核对拼写和负数规则。浮点计算则要区分显示值和实际精度。
|
||
|
||
## 选择集合
|
||
|
||
| 集合 | 关注点 | 典型选择理由 |
|
||
| --- | --- | --- |
|
||
| `Array` | 固定长度、按位置访问 | 已知元素数量 |
|
||
| `OrderedCollection` | 保留顺序、可增删 | 动态列表 |
|
||
| `SortedCollection` | 根据排序关系组织 | 持续维护顺序 |
|
||
| `Set` | 去重 | 关心是否出现 |
|
||
| `Bag` | 保留重复次数 | 计数、频次 |
|
||
| `Dictionary` | 键到值的映射 | 命名索引 |
|
||
| `IdentityDictionary` | 以身份区分键 | 相等值仍需视为不同键 |
|
||
| `Interval` | 规则数列 | 数字范围遍历 |
|
||
| `LinkedList` | 链式组织 | 研究链节点协议 |
|
||
|
||
有索引不代表所有集合都使用相同索引语义;数组和序列类的常见索引从 1 开始。
|
||
|
||
## 四种遍历意图
|
||
|
||
```smalltalk
|
||
#(2 3 4) do: [ :n | n squared ].
|
||
#(2 3 4) collect: [ :n | n squared ].
|
||
#(2 3 4) select: [ :n | n > 2 ].
|
||
#(2 3 4) inject: 0 into: [ :sum :n | sum + n ]
|
||
```
|
||
|
||
`do:` 强调逐个执行,不收集块结果;`collect:` 映射结果;`select:` 保留满足条件的元素;`inject:into:` 累积一个值。依次推演,后三条分别表达平方序列、筛出 3 和 4、求和 9。结果容器类型取决于接收者协议,不能一概写为 Array。
|
||
|
||
`add:` 的返回值可能是加入的元素;对 Dictionary,`at:put:` 表示设置键值;对固定数组则是替换槽位。共享选择子并不抹平各类的约束。
|
||
|
||
## 流把位置与内容分开
|
||
|
||
`ReadStream`、`WriteStream` 和 `ReadWriteStream` 在底层集合之上维护读取或写入位置。`next`、`nextPut:`、`atEnd` 表达逐项读、逐项写和结束判断。`contents` 用于取得流的内容,`position` 与 `reset` 处理位置。
|
||
|
||
文件流把同一思路扩展到外部文件;原书还介绍 `FileDirectory`。不要把内存流的生命周期直接套给文件:外部资源需关闭,并明确失败与部分写入的处理方式。本文没有运行文件写入示例。
|
||
|
||
## 练习
|
||
|
||
对“保留输入顺序并允许重复”“按名称找对象”“统计同一值出现几次”,依次考虑 OrderedCollection、Dictionary、Bag。再问一层:键相等采用什么语义,修改键会不会破坏查找?带着这些问题去浏览实际类的方法,能比背类名得到更多信息。
|