上QQ阅读APP看书,第一时间看更新
第3章 一切皆序列
程序操作的对象是数据。在最底层,程序面对的是字符串、列表、向量、映射表、集合和树这样的数据结构。与此同时,在较高的层面上,同样的数据结构抽象也一再出现。例如以下几个方面证明了此点。
● XML数据是一棵树。
● 数据库结果集可以被看作是列表或向量。
● 目录层次也是树。
● 文件通常被看作是一个大的字符串,或是由文本行组成的向量。
在Clojure中,所有这些数据结构都可以通过同一个抽象概念来访问:序列。
序列(seq,发音“seek”)是一种逻辑上的列表。说它是逻辑上的,是因为Clojure的序列,并没有被捆绑在某种列表的实现细节上(比如说Lisp的cons cell,列表构造单元,cons的历史参见“Cons的起源”)。相反,序列是一种抽象,可以用于任何地方。
可被视为序列的容器,被称为可序化的(seq-able,发音“SEEKa-bull”)。本章中,你会遇到各种各样可序化的容器。
● 所有的Clojure容器
● 所有的Java容器
● Java数组和字符串
● 正则表达式的匹配结果
● 目录结构
● 输入/输出流
● XML树
你还会遇到序列库,这是一组函数,对任何可序化的东西都有效。由于有太多太多的东西都是序列,所以相较其他语言中的容器 API 而言,Clojure 序列库更强大,也更通用。序列库包含了用于创建、过滤和转换数据的函数。这些函数在 Clojure 中,不仅仅扮演着容器API的角色,还替代了许多你在命令式语言中需要手工编写的循环结构。
在本章,你将会成为一名Clojure序列的进阶用户。你将会看到如何使用一组极具表达力的常用函数,来处理范围广泛到令人难以置信的数据类型。随后,在下一章(第 4章“函数式编程”),你将会学习函数式风格,本章介绍的序列库都是基于这种风格编写的。