Erlang 列表

虽然元组可以将数据组成一组,但是我们也需要表示数据列表。 Erlang 中的列表由方括号括起来表示。例如,世界上不同城市的温度列表就可以表示为:

  1. [{moscow, {c, -10}}, {cape_town, {f, 70}}, {stockholm, {c, -4}},
  2. {paris, {f, 28}}, {london, {f, 36}}]

请注意,这个列表太长而不能放在一行中,但是这并没有什么关系。Erlang 允许在 “合理的地方” 换行,但是并不允许在一些 “不合理的方”,比如原子类型、整数、或者其它数据类型的中间。

可以使用 “|” 查看部分列表。将在下面的的例子来说明这种用法:

  1. 17> [First |TheRest] = [1,2,3,4,5].
  2. [1,2,3,4,5]
  3. 18> First.
  4. 1
  5. 19> TheRest.
  6. [2,3,4,5]

可以用 | 将列表中的第一个元素与列表中其它元素分离开。First 值为 1,TheRest 的值为 [2,3,4,5]。

下一个例子:

  1. 20> [E1, E2 | R] = [1,2,3,4,5,6,7].
  2. [1,2,3,4,5,6,7]
  3. 21> E1.
  4. 1
  5. 22> E2.
  6. 2
  7. 23> R.
  8. [3,4,5,6,7]

这个例子中,我们用 | 取得了列表中的前两个元素。如果你要取得的元素的数量超过了列表中元素的总数,将返回错误。请注意列表中特殊情况,空列表(没有元素),即 []:

  1. 24> [A, B | C] = [1, 2].
  2. [1,2]
  3. 25> A.
  4. 1
  5. 26> B.
  6. 2
  7. 27> C.
  8. []

在前面的例子中,我们用的是新的变量名而没有重复使用已有的变量名: First,TheRest,E1,R,A,B 或者 C。这是因为:在同一上下文环境下一个变量只能被赋值一次。稍后会介绍会详细介绍。

下面的例子中演示了如何获得一个列表的长度。将下面的代码保存在文件 tut4.erl 中:

  1. -module(tut4).
  2. -export([list_length/1]).
  3. list_length([]) ->
  4. 0;
  5. list_length([First | Rest]) ->
  6. 1 + list_length(Rest).

编译并运行:

  1. 28> c(tut4).
  2. {ok,tut4}
  3. 29> tut4:list_length([1,2,3,4,5,6,7]).
  4. 7

代码含义如下:

  1. list_length([]) ->
  2. 0;

空列表的长度显然为 0。

  1. list_length([First | Rest]) ->
  2. 1 + list_length(Rest).

一个列表中包含第一个元素 First 与剩余元素列表 Rest, 所以列表长度为 Rest 列表的长度加上 1。

(高级话题:这并不是尾递归,还有更好地实现该函数的方法。)

一般地,Erlang 中元组类型承担其它语言中记录或者结构体类型的功能。列表是一个可变长容器,与其它语言中的链表功能相同。

Erlang 中没有字符串类型。因为,在 Erlang 中字符串可以用 Unicode 字符的列表表示。这也隐含地说明了列表 [97,98,99] 等价于字符串 “abc”。 Erlang 的 shell 是非常 “聪明" 的,它可以猜测出来列表所表示的内容,以将其按最合适的方式输出,例如:

  1. 30> [97,98,99]
  2. "abc"