programming erlang 笔记-第三章 顺序编程
第三章 顺序编程
本章让我们熟悉用erlang进行常规的顺序编程。
3.1 模块
模块是erlang中,最基本的代码组织单元,所有的代码都是以模块形式进行保存的(类似C++中的cpp,cxx,c文件)。
模块的后缀名为”erl”,编译后后缀为beam。模块的名称必须为atom(小写字母开头,可以包含字母数字,@, _,否则需要用 ” 将atom包含起来),比如我们写了一个计算几何图形面积的模块,命名为geometry.erl:
%%%geometry.erl
-module(geometry).
-export([area/1]).
area({rectangle, Width, Height}) -> Width * Height;
area({circle, R}) -> math:pi() * R * R.
上面就是一个完整的module,我相信此刻你肯定有很多的疑问,因为我刚刚接触erlang的时候也是如此。
让我错略的为您解释一下,希望能为您散去头顶丝丝的疑云。
每个moudule必须包含一些Attribute(属性)声明,以及由函数组成的代码。eralng是面向函数(FP)的编程语言,其代码中几乎处处皆函数,所有函数有返回值。上面geometry的module中,我们首先声明了module属性,注意这个属性加上erl后缀,一定就是我们保存的模块文件(如果你有破坏心理,你可以尝试一下让module声明和文件名不一致,那么后面编译的时候,一定会出现undef的错误),其次声明导出的函数列表,这就相当于输出的接口(如同C++中某个类的public函数,或者c中导出函数),这里我们只是向外暴露一个接口area,用来计算面积。接下来就是函数的定义部分了,我们的area函数包含两个clause(翻译成子句),子句用分号分割,最后一个子句作为函数的结尾用”.”结尾。在第二个子句中,我们调用了math:pi(),获取计算圆面积的PI指,这里就是erlang中函数调用的方法:M:F(A),M代表模块,F代表函数名称,A代表参数。用大括号{}包含的数据结构是tuple(这个词就不翻译了,不然有点蹩脚),与C中的struct有点类似。
经过上面一股脑的介绍,是不是明白了一些?自己动手写一下代码吧。
继续进行,写好代码以后我们需要编译:
$ > erl
1 > c(geometry).
{ok, geometry}
说明咱们的geometry编译成功!如果出现undef错误,那么很直接的告诉你,赶紧升级你erlang吧,我当前使用的R12B-3,它的math模块中有pi/1这个函数哦。
2 > geometry:area({circle, 1.4}).
6.157521601035994
我们的结果与书上的结果不一样?那是因为我们的math:pi/0比joe用的3.14159精确。
扩展这个程序
除了计算矩形和圆形,现在我们又想计算正方形的面积,好吧,别不情愿,让我们在增加一些代码。我们需要做的就是添加一个clause,现在area/1函数是这个样子:
area({rectangle, Width, Height}) -> Width * Height;
area({circle, R}) -> math:pi() * R * R; % . -> ;
area({square, X}) -> X * X.
看到我们上面的注释了么(%表示注释),我们添加了一个clause,那么我们原来以”.”结尾的子句,现在要以”;”结尾,而新添加的子句以.结尾,表明这个area/1的结束。如果你忘记了这些,好心的erlang编译器会提醒你的。
上面三个子句的顺序不是很重要,因为他们计算不同的图形的面积,我们在参数中都有标记,就是那些rectangle, [...]