模块系统

Erlang具备一套模块系统以便我们将大型程序切分为一组模块。每个模块都有自己的名称空间;这样我们就可以在不同的模块中自由地使用相同的函数名而不会有任何冲突。

模块系统以对给定模块中函数的可见性进行限制的方式来工作的。函数的调用方式取决于模块名、函数名以及函数名是否在模块的导入或导出声明中出现。

程序 2.2

  1. -module(lists1).
  2. -export([reverse/1]).
  3.  
  4. reverse(L) ->
  5. reverse(L, []).
  6.  
  7. reverse([H|T], L) ->
  8. reverse(T, [H|L]);
  9. reverse([], L) ->
  10. L.

程序2.2定义了一个颠倒列表元素顺序的函数reverse/1reverse/1是该模块中唯一可以从该模块之外被调用的函数。需要从模块外部调用的函数必须出现在模块的导出声明中。

该模块中定义的其他函数,reverse/2,仅可供模块内部使用。注意reverse/1reverse/2是完全不同的函数。在Erlang中,名字相同但参数数目不同的两个函数是完全不同的函数。

模块间调用

从其他模块中调用函数的方法有两种:

程序 2.3

  1. -module(sort1).
  2. -export([reverse_sort/1, sort/1]).
  3.  
  4. reverse_sort(L) ->
  5. lists1:reverse(sort(L)).
  6. sort(L) ->
  7. lists:sort(L).

reverse/1完全限定名称被调用。

你还可以借助import声明使用隐式限定函数名,如程序2.4所示。

程序 2.4

  1. -module(sort2).
  2. -import(lists1, [reverse/1]).
  3. -export([reverse_sort/1, sort/1]).
  4.  
  5. reverse_sort(L) ->
  6. reverse(sort(L)).
  7. sort(L) ->
  8. lists:sort(L).

两种形式都是为了解决二义性。比如,当两个不同的模块导出了重名的函数,则必须显式限定函数名。