Clojure程序设计
上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章“函数式编程”),你将会学习函数式风格,本章介绍的序列库都是基于这种风格编写的。