3.1 Tuples
特点:确定数目的item。
用于创建复杂的数据结构。
符号是'{}'。
请读者看一下2.2.4的例程,我们可以这样调用它。
> Thing = {triangle, 6, 7, 8}.
{triangle, 6, 7, 8}
>math3:area(Thing).
20.3332
这里就把Thing绑定(bound)到了一个tuple上--{triangle, 6, 7, 8},请读者注意
这里的用词:"绑定(bound)"。我们在Erlang中是没有变量的概念的,所有用到的量都是
一次性赋值,即绑定。
继续我们的Tuple...
Thing是一个有4项的tuple。第一项是原子量triangle,剩下的三项是整型数6,7,8。
其他例子:
{a, 12, b}, {}, {1, 2, 3}, {a, b, c, d ,e}.
3.2 List
特点:存储不定数目的item。
符号是'[]'
例子:
[], [a, b, 12], [22], [a, 'hello friend']
3.3 补充Data Types
-Numbers: 123, -789, 3.14159, 7.8e12, -1.2e-45.
分为整数和浮点数。
-Atoms: abc, 'An atom with spaces', monday,green,hello_world
用于把不同类型的数据组织起来。
-Tuples
-Lists
组合使用tuples 和 lists可以帮助我们创建复杂的数据结构。
X = {book, preface, acknowledgments, contents,
{chapters, [
{chapter, 1, 'An Erlang Tutorial'},
{chapter, 2, ...}
]
}},
用一个复杂的数据结构,把一本书表示了出来,美极了。
:)
处理匹配失败了怎么办?
-module(temp).
-export([convert/2]).
convert({fahrenheit, Temp}, celsius) ->
{celsius, 5 * (Temp - 32) / 9};
convert({celsius, Temp}, fahrenheit) ->
{farenheit, 32 + Temp * 9 / 5};
convert({reaumur, Temp}, celsius) ->
{celsius, 10 * Temp / 8};
convert({celsius, Temp}, reaumur) ->
{reaumur, 8 * Temp / 10};
convert({X, _}, Y) -> %匹配失败了
{cannot,convert,X,to,Y}. %处理匹配失败
运行:
> temp:convert({fahrenheit, 98.6}, celsius).
{celsius,37.0000}
> temp:convert({reaumur, 80}, celsius).
{celsius,100.000}
> temp:convert({reaumur, 80}, fahrenheit).
{cannot,convert,reaumur,to,fahrenheit}
程序中使用了一个下划线'_'来捕捉失败的情况,这个'_'的作用像是C中的default
它表示:这里有一个值,但这个值具体是什么我不关心。
注意这个东西一定要放到最好,这一点不像C中的default,Erlang有些地方不是很
智能,这也许是基于电信中的效率考虑吧。设想热恋中,你鼓足勇气要说"I love you"
之类的东西了,这时候,电信信息要升级、匹配什么的,总之是断了一下......这让你
觉得有什么先兆,胡思乱想... ...“算了,不说了”....
效率就是一切,把一切都交给程序员吧。
{12,banana}
> {A, B} = N.
{12,banana}
> A.
12
> B.
banana
4. 并发编程
Erlang是并行语言。
也就是说Erlang对并行的支持是语言级别的,不需要操作系统的支持。
'spawn'启动一个过程(process),给一个process发消息,从一个process收消息。
'spawn/3'启动一个process并返回一个标识(identifier),这个标识用于收、发
消息。
语法: Pid ! Msg
Example: Pid ! {a, 12}
Pid : identifier
! : 发消息标识
{a, 12} : 一条消息
所有参数在发消息之前都要计算(比较:Erlang中是懒惰求值的,但是在发消息的
时候,必须提前计算)。
Example: foo(12) ! math3:area({square, 5})
计算foo(12) 和 math3:area({square, 5}),但是两边的计算规则是未定义的。
〔
这一段翻译的不好,原文:
foo(12) ! math3:area({square, 5})
means evaluate the function foo(12) (this must yield a valid process
identifier) and evaluate math3:area({square, 5}) then send the result
(i.e. 25) as a message to the process. The order of evaluation of the
two sides of the send primitive is undefined.
〕
'receive'原语,用于收消息。
语法:
receive
Message1 ->
... ;
Message2 ->
... ;
...
end
MessageN,执行这个消息'->'后面的语句。
如果收到的消息,没有匹配上receive...end中定义的模式,这个收消息的过
程将挂起,等待处理下一条消息;未匹配的消息,将保存,等待后续处理。
Example:
{A, Msg}
A --------------------------------->B
Msg
A<----------------------------------B
An echo process
-export([start/0, loop/0]).
start() ->
spawn(echo, loop, []).
receive
{From, Message} ->
From ! Message,
loop()
end.
Id = echo:start(),
Id ! {self(), hello}.
self()是个内建函数(BIF),返回该过程的identifier