Files
endorphin-tabularium-docs/content/docs/smalltalk/06-collections-and-streams.md
T

3.3 KiB
Raw Blame History

基础类库:数值、集合与流

原书依据:第 9–12 章,印刷页 53–90,PDF 页 64–101。

这些章节适合按“要保存什么、如何比较、如何遍历”阅读。具体消息是否存在仍以书中 Version 2 镜像为范围。

有序值与数值

Magnitude 抽象可比较对象;原书讨论其下的 Date、Time、Character 与数值体系。日期和时间章节的构造协议具有历史性,不能直接当作时区或国际化指南。字符章节基于当时的有限字符集合,不能扩展成 Unicode 结论。

Number 的主要子类包含 Integer、Fraction 和 Float。整数层级还区分小整数与大整数。算术消息的结果可以由不同数值类表示,不能仅根据左操作数认定返回类型。

1 / 3
7 // 2
7 \\ 2

在原书数值模型中,第一条可以表示精确分数,后两条分别体现整除和余数协议。这里的余数选择子写作两个反斜杠;使用其他方言时务必核对拼写和负数规则。浮点计算则要区分显示值和实际精度。

选择集合

集合 关注点 典型选择理由
Array 固定长度、按位置访问 已知元素数量
OrderedCollection 保留顺序、可增删 动态列表
SortedCollection 根据排序关系组织 持续维护顺序
Set 去重 关心是否出现
Bag 保留重复次数 计数、频次
Dictionary 键到值的映射 命名索引
IdentityDictionary 以身份区分键 相等值仍需视为不同键
Interval 规则数列 数字范围遍历
LinkedList 链式组织 研究链节点协议

有索引不代表所有集合都使用相同索引语义;数组和序列类的常见索引从 1 开始。

四种遍历意图

#(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。再问一层:键相等采用什么语义,修改键会不会破坏查找?带着这些问题去浏览实际类的方法,能比背类名得到更多信息。