模块与函数
如果一种编程语言只能通过 shell 来运行代码,那么这种语言基本上没什么太大的用处,Erlang 同样可以通过脚本来运行程序。这里有一小段 Erlang 程序。使用合适的文本编辑器将其输入到文件 tut.erl 中。文件名称必须为 tut.erl 不能任意修改,并且需要将其放置于你启动 erl 命令时所在的目录下。如果恰巧你的编辑器有 Erlang 模式的话,那么编辑器会帮助你优雅地组织和格式化你的代码 (参考 Emacs 的 Erlang 模式),不过即使你没有这样的编辑器你也可以很好地管理你自己的代码。下面是待输入的代码:
-module(tut).
-export([double/1]).
double(X) ->
2 * X.
很容易就可以看出来这个程序将数值翻倍。开始两行的代码稍后会解释。让我们来编译一下这段代码。我们可以在 Erlang shell 下来完成这个任务,其中 c 代表编译(compile)的意思:
3> c(tut).
{ok,tut}
{ok,tut} 说明编译成功。如果返回 “error” 则表示输入的代码中存在错误。其它相关的错误信息可以帮助你弄清楚错误的位置和原因,然后你可以根据错误提示修改并重新编译代码。
下面运行这个程序:
4> tut:double(10).
20
和预期结果一样,10 乘以 2 后就是 20。
让我们先回到代码最开始的这两行。每个的 Erlang 程序的文件都包含一个 Erlang 模块。模块中代码的第一个行就是该模块的名字(参见 模块)。
-module(tut).
因此,这个模块名为 tut。请注意该行代码结束后的句号 “.”。存储模块的文件必须与模块同名,并且以 “.erl” 作为扩展。在这个例子中,文件名为 tut.erl。如果使用到另外一个模块中的一个函数,可以使用如下的语法 :module_name:function_name(arguments)。因此,下面的代码的含义也就是调用模块 tut 中的函数 double,并且传递的实参为 10。
4> tut:double(10).
第二行声明 tut 模块中包含一个 double 函数,此函数接受一个参数 (在本例中为 x):
-export([double/1]).
同时,第二行声明也说明了这个函数可以在 tut 模块外被其它模块调用。后面会详细说明这一点。请再次注意这一行末尾的句号。
接下来给出一个更加复杂的例子,计算一个数的阶乘。比如,4 的阶乘即为 432*1,等于 24。
在 tut1.erl 文件中输入如下的一段代码:
-module(tut1).
-export([fac/1]).
fac(1) ->
1;
fac(N) ->
N * fac(N - 1).
所以在模块 tut1 中存在一个函数 fac,此函数接受一个输入参数 N。
第一部分说明的是 1 的阶乘即为 1:
fac(1) ->
1;
需要注意的是,这一部分是以分号结束的,这也就表示后面还有 fac 函数的更多内容。
第二部分表示 N 的阶乘为 N 乘以 N-1 的阶乘:
fac(N) ->
N * fac(N - 1).
与前面不同,这部分是以句号结尾的。这也就是说,后面没有这个函数更多的内容了。
编译这个文件:
5> c(tut1).
{ok,tut1}
下面计算 4 的阶乘:
6> tut1:fac(4).
24
调用 tut1 模块中的 fac 函数,传入的参数为 4。
与其它语言一样,Erlang 函数也可以有多个参数,让我们扩展 tut1 模块,实现一个函数完成两个数相乘:
-module(tut1).
-export([fac/1, mult/2]).
fac(1) ->
1;
fac(N) ->
N * fac(N - 1).
mult(X, Y) ->
X * Y.
需要注意,扩展模块时,需要修改 -export 这一行。在这一行中添加另外一个接受两个参数的函数 mult。
编译:
7> c(tut1).
{ok,tut1}
使用一下新函数:
8> tut1:mult(3,4).
12
在这个例子中,数字是整数值,代码中函数的参数 N、X 与 Y 被称之为变量。变量必须以大写字母开始 (参考变量)。诸如,Number、ShoeSize 和 Age 都是变量。