after and andalso band begin bnot bor bsl bsr bxor case catch cond div end fun if let not of or orelse query receive rem try when xor
基本都是些用于逻辑运算、位运算以及特殊表达式的符号 2.Erlang的类型,除了在前面入门一提到的类型外,还包括: 1)Binary,用于表示某段未知类型的内存区域 比如: 1> <<10,20>>. <<10,20>> 2> <<"ABC">>. <<65,66,67>> 2)Reference,通过调用mk_ref/0产生的运行时的unique term 3)String,字符串,Erlang中的字符串用双引号包括起来,其实也是list。编译时期,两个邻近的字符串将被连接起来,比如"string" "42" 等价于 "string42" 4)Record,记录类型,与c语言中的struct类似,模块可以通过-record属性声明,比如: -module(person). -export([new/2]). -record(person, {name, age}). new(Name, Age) -> #person{name=Name, age=Age}. 1> person:new(dennis, 44). {person,dennis,44} 在编译后其实已经被转化为tuple。可以通过Name#person.name来访问Name Record的name属性。 3.模块的预定义属性: -module(Module). 声明模块名称,必须与文件名相同 -export(Functions). 指定向外界导出的函数列表 -import(Module,Functions). 引入函数,引入的函数可以被当作本地定义的函数使用 -compile(Options). 设置编译选项,比如export_all -vsn(Vsn). 模块版本,设置了此项,可以通过 beam_lib:version/1 获取此项信息 可以通过-include和-include_lib来包含文件,两者的区别是include-lib不能通过绝对路径查找文件,而是在你当前Erlang的lib目录进行查找。 4.try表达式,try表达式可以与catch结合使用,比如: try Expr catch throw:Term -> Term; exit:Reason -> {'EXIT',Reason} error:Reason -> {'EXIT',{Reason,erlang:get_stacktrace()}} end 不仅如此,try还可以与after结合使用,类似java中的try..finally,用于进行清除作用,比如: termize_file(Name) -> {ok,F} = file:open(Name, [read,binary]), try {ok,Bin} = file:read(F, 1024*1024), binary_to_term(Bin) after file:close(F) end. 5.列表推断(List Comprehensions),函数式语言特性之一,Erlang中的语法类似: [Expr || Qualifier1,...,QualifierN] Expr可以是任意的表达式,而Qualifier是generator或者filter。还是各举例子说明下。 1> [X*2 || X <- [1,2,3]]. [2,4,6] 2> L=[1,2,3,4,5,6,7]. [1,2,3,4,5,6,7] 3> [X|X<-L,X>=3]. [3,4,5,6,7] 再看几个比较酷的例子,来自Programming Erlang, 比如快速排序: -module(qsort). -export([qsort/1]). qsort([])->[]; qsort([Pivot|T])-> qsort([X||X<-T,X<Pivot]) ++ [Pivot] ++ qsort([X||X<-T,X>=Pivot]). 搜索勾股数组: %勾股数组 -module(pythag). -export([pythag/1]). pythag(N)-> L=lists:seq(1,N), Square=fun(X) when is_number(X)->X*X end, [{A,B,C}|| A<-L, B<-L, C<-L, A+B+C=<N, Square(A)+Square(B)=:=Square(C)]. 列表推断将大大减少你的敲击键盘的次数。 6.宏,定义常量或者函数等等,语法如下: -define(Const, Replacement). -define(Func(Var1,...,VarN), Replacement). 使用的时候在宏名前加个问号?,比如?Const,Replacement将插入宏出现的位置。系统预定义了一些宏:?MODULE 表示当前模块名?MODULE_STRING 同上,但是以字符串形式?FILE 当前模块的文件名?LINE 调用的当前代码行数?MACHINE 机器名 Erlang的宏与C语言的宏很相似,同样有宏指示符,包括: -undef(Macro). 取消宏定义 -ifdef(Macro). 当宏Macro有定义的时候,执行以下代码 -ifndef(Macro). 同上,反之 -else. 接在ifdef或者ifndef之后,表示不满足前者条件时执行以下代码 -endif. if终止符 假设宏-define(Square(X),X*X).用于计算平方,那么??X将返回X表达式的字符串形式,类似C语言中#arg 一个简单的宏例子: - module(macros_demo). - ifdef(debug). - define(LOG(X), io:format( " {~p,~p}: ~p~n " , [?MODULE,?LINE,X])). - else . - define(LOG(X), true). - endif. - define(Square(X),X * X). - compile(export_all). test() -> A = 3 , ?LOG(A), B = ?Square(A), io:format( " square(~w) is ~w~n " ,[A,B]). 当编译时不开启debug选项的时候: 17> c(macros_demo). {ok,macros_demo} 18> macros_demo:test(). square(3) is 9 当编译时开启debug之后: 19> c(macros_demo,{d,debug}). {ok,macros_demo} 20> macros_demo:test(). {macros_demo,11}: 3 square(3) is 9 ok 可以看到LOG的输出了,行数、模块名以及参数 7、 Process Dictionary,每个进程都有自己的process dictionary,用于存储这个进程内的全局变量,可以通过下列 BIFs操作: put(Key, Value) get(Key) get() get_keys(Value) erase(Key) erase() 8、关于分布式编程,需要补充的几点 1)节点之间的连接默认是transitive,也就是当节点A连接了节点B,节点B连接了节点C,那么节点A也与节点C互相连接 可以通过启动节点时指定参数-connect_all false来取消默认行为 2)隐藏节点,某些情况下,你希望连接一个节点而不去连接其他节点,你可以通过在节点启动时指定-hidden选项 来启动一个hidden node。在此情况下,通过nodes()查看所有连接的节点将不会出现隐藏的节点,想看到隐藏的节点 可以通过nodes(hidden)或者nodes(connected)来查看。 完整的erl选项如下: -connect_all false 上面已经解释。 -hidden 启动一个hidden node -name Name 启动一个系统成为节点,使用long name. -setcookie Cookie 与Erlang:set_cookie(node(), Cookie).相同,设置magic cookie -sname Name 启动一个Erlang系统作为节点,使用short name 注意, short name启动的节点是无法与long name节点通信的。 9.一个小细节,在Erlang中小于等于是用=<表示,而不是一般语言中的<=语法,我犯过错误的地方,同样,不等于都是用/号,而不是 !,比如/=、=/=。 10.and or 和andalso orelse的区别 and和or会计算两边的表达式,而andalso和orelse的求值采用短路机制,比如exp1 andalso exp2,当exp1返回false之后,就不会去求值 exp2,而是直接返回false,而exp1 and exp2会对exp1和exp2都进行求值,or与orelse也类似。 今天在 erlang-china下到了《Programming Erlang》,准备打印一份看看,进入OTP的学习。 文章转自庄周梦蝶 ,原文发布时间2007-07-24 相关资源:敏捷开发V1.0.pptx