返回首页 Erlang 教程中文版

顺序编程

并发编程

记录与宏

原子类型

原子类型是 Erlang 语言中另一种数据类型。所有原子类型都以小写字母开头 (参见 原子类型)。例如,charles,centimeter,inch 等。原子类型就是名字而已,没有其它含义。它们与变量不同,变量拥有值,而原子类型没有。

将下面的这段程序输入到文件 tut2.erl 中。这段程序完成英寸与厘米之间的相互转换:

-module(tut2).
-export([convert/2]).

convert(M, inch) ->
    M / 2.54;

convert(N, centimeter) ->
    N * 2.54.

编译:

9> c(tut2).
{ok,tut2}

测试:

10> tut2:convert(3, inch).
1.1811023622047243
11> tut2:convert(7, centimeter).
17.78

注意,到目前为止我们都没有介绍小数(符点数)的相关内容。希望你暂时先了解一下。

让我们看一下,如果输入的参数既不是 centimeter 也不是 inch 时会发生什么情况:

12> tut2:convert(3, miles).
** exception error: no function clause matching tut2:convert(3,miles) (tut2.erl, line 4)

convert 函数的两部分被称之为函数的两个子句。正如你所看到的那样,miles 并不是子句的一部分。Erlang 系统找不到匹配的子句,所以返回了错误消息 function_clause。shell 负责被错误信息友好地输出,同时错误元组会被存储到 shell 的历史列表中,可以使用 v/1 命令将该列表输出:

13> v(12).
{'EXIT',{function_clause,[{tut2,convert,
                                [3,miles],
                                [{file,"tut2.erl"},{line,4}]},
                          {erl_eval,do_apply,5,[{file,"erl_eval.erl"},{line,482}]},
                          {shell,exprs,7,[{file,"shell.erl"},{line,666}]},
                          {shell,eval_exprs,7,[{file,"shell.erl"},{line,621}]},
                          {shell,eval_loop,3,[{file,"shell.erl"},{line,606}]}]}}

元组

前面的 tut2 的程序的风格不是一好的编程风格。例如:

tut2.convert(3,inch)  

这是意味着 3 本身已经是英寸表示了呢?还是指将 3 厘米转换成英寸呢? Erlang 提供了将某些元素分成组并用以更易于理解的方式表示的机制。它就是元组。一个元组由花括号括起来的。

所以,{inch,3} 指的就是 3 英寸,而 {centimeter, 5} 指的就是 5 厘米。接下来,我们将重写厘米与英寸之间的转换程序。将下面的代码输入到文件 tut3.erl 文件中:

-module(tut3).
-export([convert_length/1]).

convert_length({centimeter, X}) ->
    {inch, X / 2.54};
convert_length({inch, Y}) ->
    {centimeter, Y * 2.54}.

编译并测试:

14> c(tut3).
{ok,tut3}
15> tut3:convert_length({inch, 5}).
{centimeter,12.7}
16> tut3:convert_length(tut3:convert_length({inch, 5})).
{inch,5.0}

请注意,第 16 行代码将 5 英寸转换成厘米后,再转换为就英寸,所以它得到原来的值。这也表明,一个函数实参可以是另一个函数的返回结果。仔细看一下,第 16 行的代码是怎么工作的。将参数 {inch,5} 传递给函数后,convert_length 函数的首语句的头首先被匹配,也就是 convert_length({inch,5}) 被匹配。也可以看作,{centimeter, X} 没有与 {inch,5} 匹配成功 ("->" 前面的内容即被称之为头部)。第一个匹配失败后,程序会尝试第二个语句,即 convert_length({inch,5})。 第二个语句匹配成功,所以 Y 值也就为 5。

元组中可以有更多的元素,而不仅仅像上面描述的那样只有两部分。事实上,你可以在元组中,使用任意多的部分,只要每个部分都是合法的 Erlang 的项。例如,表示世界上不同城市的温度值:

{moscow, {c, -10}}
{cape_town, {f, 70}}
{paris, {f, 28}}

这些元组中每个都有固定数目的项。元组中的每个项都被称之为一个元素。在元组 {moscow,{c,-10}} 中,第一个元素为 moscow 而第二个元素为 {c,-10}。其中,c 表示摄氏度,f 表示华氏度。

上一篇: 模块与函数 下一篇: 列表