虽然Erlang本身是一种很有吸引力的编程语言,但当你把它与虚拟机(VM)、OTP中间件和类库相结合的时候,其真正的实力才能完全体现出来。其中的每一点都使Erlang软件开发变得如此特别。那么,具体有哪些功能体现出Erlang与其他类似语言的不同呢?
高级构造
Erlang是一种声明性的语言。声明性语言工作的原则是去描述应该计算什么,而不是去解释这个值是如何计算而来的。一个函数定义就像一组等式,尤其是当使用模式匹配从不同的情况中去选择和从复杂的数据结构中抽取组件的时候。下面是一个简单的例子:
area({square, Side}) -> Side * Side ;
area({circle, Radius}) -> math:pi() * Radius * Radius.
这个函数定义包含一个形状参数(这里是一个方形或者圆形),依靠它收到的形状类型,系统匹配正确的函数定义,并返回面积计算结果。
在Erlang中,不仅可以对高层数据进行模式匹配,而且同样可以对二进制序列数据进行匹配。下面是一个解码TCP数据包的函数开始部分:
decode(<< SourcePort:16, DestinationPort:16,
SequenceNumber:32,
AckNumber:32,
DataOffset:4, _Reserved:4, Flags:8, WindowSize:16,
Checksum:16, UrgentPointer:16,
Payload/binary>>) when DataOffset>4 ...
在前面的代码中,每个长度的数字,比如在DataOffset:4中的4,给出了可以与变量相匹配的位数。相比之下,可以设想一下同样的效果如何在C或Java语言中实现呢?
Erlang的另一个特性是,函数(或者闭包)属于第一类数据。可以把它们绑定到一个变量上,也可以像其他数据一样处理它们:在一个列表中存储,以一个函数方式返回,或在不同的进程中传递它们。
Erlang中的列表解析(list comprehension)借鉴了函数式编程范例,它结合了列表生成器(list generator)和过滤器(filter),返回在使用过滤器后由一个列表生成器产生的部分元素的列表。下面是列表解析的一个例子,它只用几行代码就实现了快速排序算法。我们将在第9章中更详细地介绍列表解析。
qsort([]) -> [];
qsort([X|Xs]) ->
qsort([Y || Y<-Xs, Y =< X]) ++ [X] ++ qsort([Y || Y<-Xs, Y > X]).
并发进程和消息传递
并发是Erlang成功的根本。Erlang不提供共享内存的线程,而是每个Erlang进程都在它自己的内存空间里执行,并拥有它自己的堆和栈。 进程之间不能随意相互干扰,而这在线程模型中很容易发生,从而极易导致死锁和其他可怕的事情。
进程之间通过消息传递进行相互交流,而这个消息可以是Erlang中的任意数据。消息传递是异步的,因此一旦消息发送,这一进程就能够马上继续执行。消息是有选择性地取自进程信箱,因此没有必要按照消息的到达顺序来处理它们。特别是当进程处理发生在不同的计算机上,并且消息收取的顺序依赖于周围的网络环境的时候,这使并发更为健壮。图1-1给出了一个例子,使用一个“area server”进程为客户计算图形的面积,就像我们在“高级构造”一节中提到的那样。
Erlang编程指南——Erlang的特性
书名: Erlang编程指南
作者:
出版社: 机械工业出版社
原作名: Erlang Programming
译者: 慕尼黑Isar工作组 | Simon Thompson
出版年: 2011-3
页数: 444
定价: 79.00元
装帧: 平装
ISBN: 9787111303251