首页 > Erlang并发教程 > 2.1 Erlang并发编程-串行编程
2013
11-04

2.1 Erlang并发编程-串行编程

程序1.1用于计算整数的阶乘:

程序1.1

-module(math1).
-export([factorial/1]).

factorial(0) -> 1;
factorial(N) -> N * factorial(N - 1).

函数可以通过shell程序进行交互式求值。 Shell会提示输入一个表达式,并计算和输出用户输入的任意表达式,例如:

> math1:factorial(6).
720
> math1:factorial(25).
15511210043330985984000000

以上的“>”代表 shell 提示符,该行的其他部分是用户输入的表达式。之后的行是表达式的求值结果。

factorial 的代码如何被编译并加载至 Erlang 系统中是一个实现相关的问题。 [1]

在我们的例子中,factorial函数定义了两个子句:第一个子句描述了计算factorial(0)的规则,第二个是计算factorial(N)的规则。当使用某个参数对factorial进行求值时,两个子句按照它们在模块中出现的次序被依次扫描,直到其中一个与调用相匹配。当发现一个匹配子句时,符号->右边的表达式将被求值,求值之前函数定义式中的变量将被代入右侧的表达式。

所有的 Erlang 函数都从属于某一特定模块。最简单的模块包含一个模块声明、导出声明,以及该模块导出的各个函数的实现代码。导出的函数可以从模块外部被调用。其他函数只能在模块内部使用。

程序1.2是该规则的一个示例。

程序1.2

-module(math2).
-export([double/1]).

double(X) ->
    times(X, 2).

times(X, N) ->
    X * N.

函数double/1可在模块外被求值[2]times/2则只能在模块内部使用,如:

> math2:double(10).
20
> math2:times(5, 2).
** undefined function: math2:times(5,2) **

在程序1.2中模块声明-module(math2)定义了该模块的名称,导出属性-export([double/1])表示本模块向外部导出具备一个参数的函数double

函数调用可以嵌套:

> math2:double(math2:double(2)).
8

Erlang 中的选择是通过模式匹配完成的。程序 1.3 给出一个示例:

程序1.3

-module(math3).
-export([area/1]).

area({square, Side}) ->
    Side * Side;
area({rectangle, X, Y}) ->
    X * Y;
area({circle, Radius}) ->
    3.14159 * Radius * Radius;
area({triangle, A, B, C}) ->
    S = (A + B + C)/2,
    math:sqrt(S*(S-A)*(S-B)*(S-C)).

如我们所期望的,对math3:area({triangle, 3, 4, 5})得到6.0000math3:area({square, 5})得到 25 。程序1.3 引入了几个新概念:

元组——用于替代复杂数据结构。我们可以用以下 shell 会话进行演示:

> Thing = {triangle, 6, 7, 8}.
{triangle, 6, 7, 8}
> math3:area(Thing).
20.3332

此处Thing被绑定到{triangle, 6, 7, 8}——我们将Thing称为尺寸为4的一个元组——它包含 4 个元素。第一个元素是原子式triangle,其余三个元素分别是整数6、7和8。

模式识别——用于在一个函数中进行子句选择。area/1被定义为包含4个子句。以math3:area({circle, 10})为例, 系统会尝试在area/1定义的子句中找出一个与{circle, 10}相符的匹配,之后将函数定义头部中出现的自由变量Radius绑定到调用中提供的值(在这个例子中是10)。

序列临时变量——这二者是在area/1定义的最后一个子句中出现的。最后一个子句的主体是由两条以逗号分隔的语句组成的序列;序列中的语句将依次求值。函数子句的值被定义为语句序列中的最后一个语句的值。在序列中的第一个语句中,我们引入了一个临时变量S


2.1 Erlang并发编程-串行编程》有 1 条评论

  1. 剑波 说:

    shell 提示符 出不来

留下一个回复

你的email不会被公开。