业精于勤,荒于嬉
全部博文(763)
分类: LINUX
2013-07-15 11:41:52
erlang的process并不是OS的进程,而是虚拟的进程;进程之间的切换是在用户态进行,开销会比OS的进程小得多。
以后只要提到进程,没有特殊说明,都是指erlang的进程;
最多能有多少进程?没有明确限制,与内存有关,物理内存用完时,会使用虚拟内存;
OTP: Open Telecom Platform,
不要被名字所混淆,它实际上是用于一套搭建分布式高容错**器的程序库;
变量只能被赋值一次,即不能写这样代码:X = X+1
可赋值的变量,但仅可赋值一次,不能再修改;
只能用大写字母开头,并且用大写字母开头的字符串一律会被视为Variable;
也就是说:函数也不能用大写开头
“Absence of Side Effects MeansWe Can Parallelize Our Programs”
例子:
X = 123456789.
其中X就是变量
Atom用来表示非数字的常量;
以小写字面开头,后面可以是字母、下划线或者@字符
如果要用大写字母开头的atom,可以使用单引号括起来;
例子:
X = ok
其中ok就是atom,X为变量;
“a fixed number of items into a single entity;”
用{}包括起来的数据类型;类似C语言的struct;
如{apples,10}, 第一项是atom类型,第二项是数字
Tuple可以嵌套,它的元素也可以是tuple;
Tuple里面的数据不像C++、Java有变量名,因此,习惯于将他们的第一个数据用atom变量来做描述;
例子:
Person = {person,
{name, joe},
{height, 1.82},
{footsize, 42},
{eyecolour, brown}}.
这个tuple里就用第一项来表示名字;
用[]包括起来的数据类型,如[{apples,10},{pears,6},{milk,3}]
List的展开:[X|Y] = L.
X将被赋值为L的第一个子项,Y为除了第一个子项外的其它子项;
这种展开的方式将很利于递归遍历;
例子:
ThingsToBuy1 = [{oranges,4},{newspaper,1}|ThingsToBuy].
[Buy1|ThingsToBuy2] = ThingsToBuy1.
第一句是进行list的赋值;
第二句则将list分成两部分,以准备进行进一步操作;
String其实是list;
比如[83,117,114,112,114,105,115,101]. 其实是“Surprise”
Erlang字符集是Latin-1(ISO-8859-1),
目前最新的版本里,erlang已经加入了Unicode的支持
Tuple对象,当成员很多时,会很难记忆,record就是为了解决这个问题;
Record declarations can be used only in Erlang source code modules and not in the shell.
Record就是tuple,但在源码中可以让tuple使用起来想C语言的struct一样
在shell里面使用之前,要先用rr进行预处理,但源码好像不需要
-record(todo, {status=reminder,who=joe,text}).
1> rr(”records.hrl”).
[todo]
2>X=#todo{}.
#todo{status = reminder,who = joe,text = undefined}
3> X1 = #todo{status=urgent, text=”Fix errata in book”}.
#todo{status = urgent,who = joe,text = “Fix errata in book”}
4> X2 = X1#todo{status=done}.
#todo{status = done,who = joe,text = “Fix errata in book”}
5> #todo{who=W, text=Txt} = X2.
#todo{status = done,who = joe,text = “Fix errata in book”}
6> W.
joe
7> Txt.
“Fix errata in book”
X > Y X大于Y
X < Y X小于Y
X =< Y X小于或等于Y
X >= Y X大于或等于Y
X == Y X等于Y
X /= Y X不等于Y
X =:= Y X与Y完全相等(包括数据类型)
X =/= Y X与Y不完全相等
L ++ L2 list append
Erlang中的“.”(Period)表示完整函数、参数、数据结果的定义结束;
Erlang中的“,”(Comma)用来分隔参数、模式匹配等,与C语言类似;
在语句中间出现时,表示两个语句是顺序执行的关系;
Erlang中的“;”(Semicolon)用来表示分支,前后句的关系是或;
Pattern1 ->
Expressions1;
Pattern2 ->
Expressions2;
先匹配Pattern1,如果匹配成功,执行表达式Expressions1,如果不成功,匹配Pattern2
例子:
check(A) ->
if
A > 0, A=<100 ->
io:format(”>0″);
A > 100 ->
io:format(”>100″)
end.
模式匹配是erlang语法里面非常关键的内容,在赋值、函数定义、条件判定各种情况都会出现;
比如:{X, Y} = {1,2},这个赋值就完成了依次模式匹配,如果成功,将会吧X赋值为1,Y赋值为2;
模式匹配的例子:
Pattern |
Term |
Result |
{X,abc} |
{123,abc} |
Succeeds X → 123 |
{X,Y,Z} |
{222,def,”cat”} |
Succeeds X → 222, Y→ def, Z → “cat” |
{X,Y} |
{333,ghi,”cat”} |
Fails—the tuples have different shapes |
X |
True |
Succeeds X → true |
{X,Y,X} |
{{abc,12},42,{abc,12}} |
SucceedsX→{abc,12}, Y→ 42 |
{X,Y,X} |
{{abc,12},42,true} |
Fails—X cannot be both {abc,12} and true |
[H|T] |
[1,2,3,4,5] |
Succeeds H→1, T→[2,3,4,5] |
[H|T] |
“cat” |
Succeeds H→99, T →“at” |
[A,B,C|T] |
[a,b,c,d,e,f] |
Succeeds A→a, B→ b, C→ c, T→ [d,e,f] |
一种非常灵活的表达式,可以放在各种场景下使用,它的结果要么是true,要么是false;是对模式匹配的有力扩展;
使用场景举例:
在函数定义时使用:
fun(arg) when Guard -> Expressions.
例子:
max(X, Y) when X > Y -> X;
max(X, Y) -> Y.
在if语句中使用:
if
Guard -> Expressions;
Guard -> Expressions;
…
true -> Expressions
end
例子:
check(A) ->
if
A > 0, A=<100 ->
io:format(”>0″);
A > 100 ->
io:format(”>100″)
end.
在case语句中:
case Expression of
Pattern1 [when Guard1] -> Expr_seq1;
Pattern2 [when Guard2] -> Expr_seq2;
…
end
例子:
check2(A, B) ->
case A of
0 when B>0 -> io:format(”A:0 B>0″);
0 -> io:format(”A:0 B=0″);
else -> io:format(”else”)
end.
组合使用的guard:
Guard Sequences: either a single guard or a series of guards, separated by semicolons (;)
Guard1; Guard2; Guard3; Guard4
Guard: a series of guard expressions, separated by commas (,).
Guard1, Guard2, Guard3, Guard4
Guard的使用限制:
In addition, guards cannot be user-defined boolean expressions, since we want to guarantee that they are side effect free and terminate.
所以,Guard不能是自定义的表达式,只能是:
1,The atom true
2,Other constants(terms and bound variables),all evaluate to false
3,Calls to the guard predicates and to the BIFs
4,Term comparisons
5,Arithmetic expressions
6,Boolean expressions
7,Short-circuit boolean expressions
case表示式类似于C++里面的switch,不过更为强大;
case Expression of
Pattern1 [when Guard1] -> Expr_seq1;
Pattern2 [when Guard2] -> Expr_seq2;
…
end
首先执行Expression,执行的结果进行Pattern模式匹配,匹配成功,则返回Expr_seq的结果;从第一个开始,逐一进行匹配,直到匹配到为止,如果无一匹配成功,会抛出异常;
例子:
filter(P, [H|T]) ->
case P(H) of
true -> [H | filter(P, T)];
false -> filter(P, T)
end;
filter(P, []) ->
[].
表达其它的方式:
Case Expression of
{true, Data} -> io:format(”ok”);
Others -> io:format(”~p~n”, xxx)
end.
同函数名,参数个数相同的函数被视为同一个函数,各个函数定义指尖必须用分号“;”(Semicolon)分隔,存在“或”的关系,根据模式匹配结果决定调用到哪里;
例子:
area({rectangle, Width, Ht}) -> Width * Ht;
area({square, X}) -> X * X;
area({circle, R}) -> 3.14159 * R * R.
这表明,当函数的第一个参数是rectangle时,调用到第一个函数,是square时,调用到第二个函数,依次类推;
同函数名,不同参数个数的函数视为不同的函数;
funs是匿名的函数,可以方便定义小函数,并马上使用,类似python的lambda函数;
例子:
Z = fun(X) -> 2*X end.
Z(2).
loop() ->
xxx(),
loop().
这种写法最后的loop()调用叫tail-recursive,这种调用是用goto实现的,所以不会消耗调用堆栈的空间;