Erlang入门(一)
读erlang.org上面的Erlang Course四天教程
1.数字类型,需要注意两点
1)B#Val表示以B进制存储的数字Val,比如
5
二进制存储的101就是10进制的5了
2)$Char表示字符Char的ascii编码,比如$A表示65
2.比较难以翻译的概念——atom,可以理解成常量,它可以包含任何字符,以小写字母开头,如果不是以小写字母开头或者是字母之外的符号,需要用单引号包括起来,比如abc,'AB'
3.另一个概念——Tuple,有人翻译成元组,可以理解成定长数组,是Erlang的基础数据结构之一:
{1,2,3,4,5}
9> {a,b,c,1,2}.
{a,b,c,1,2}
10> size({1,2,3,a,b,c}).
6
内置函数size求长度,元组可以嵌套元组或者其他结构。下面所讲的列表也一样。
4.另外一个基础数据结构就是各个语言都有的list(列表),在[]内以,隔开,可以动态改变大小,
[123, def, abc]
[{person, 'Joe', 'Armstrong'},
{person, 'Robert', 'Virding'},
{person, 'Mike', 'Williams'}
]
可以使用内置函数length求列表大小。以""包含的ascii字母代表一个列表,里面的元素就是这些字母的ascii值,比如"abc"表示列表[97,98,99]。
5.通过这两个数据结构可以组合成各种复杂结构,与Lisp的cons、list演化出各种结构一样的奇妙,Erlang也可以当作是操作列表的语言。
6.Erlang中变量有两个特点:
1)变量必须以大写字母或者下划线开头,可以包含字母、下划线和@
2)变量只能绑定一次,也就是所谓的Single Assignment。或者以一般的说法就是只能赋值一次,其实Erlang并没有赋值这样的概念,=号也是用于验证匹配。
7.模式匹配——Pattern Matching,Erlang的模式匹配非常强大,看了buaawhl的《Erlang语法提要》的介绍,模式匹配的功能不仅仅在课程中介绍的数据结构的拆解,在程序的分派也扮演重要角色,或者说Erlang的控制的流转是通过模式匹配来实现的。具体功能参见链接,给出书中拆解列表的例子:
Succeeds - binds A = 1, B = 2,
C = [3,4,5,6,7]
[H|T] = [1,2,3,4]
Succeeds - binds H = 1, T = [2,3,4]
[H|T] = [abc]
Succeeds - binds H = abc, T = []
[H|T] = []
Fails
下面会给出更多模式匹配的例子,给出一个模块用来计算列表等
8.Erlang中函数的定义必须在一个模块内(Module),并且模块和函数的名称都必须是atom,函数的参数可以是任何的Erlang类型或者数据结构,函数要被调用需要从模块中导出,函数调用的形式类似:
moduleName:funcName(Arg1,Arg2,...).
写我们的第一个Erlang程序,人见人爱的Hello World:
-export([run/1]).
run(Name)->
io:format("Hello World ~w~n",[Name]).
存为helloWorld.erl,在Erlang Shell中执行:
{ok,helloWorld}
3> helloWorld:run(dennis).
Hello World dennis
ok
打印出来了,现在解释下程序构造,
这一行声明了模块helloWorld,函数必须定义在模块内,并且模块名称必须与源文件名相同。
而这一行声明导出的函数,run/1指的是有一个参数的run函数,因为Erlang允许定义同名的有不同参数的多个函数,通过指定/1来说明要导出的是哪个函数。
接下来就是函数定义了:
io:format("Hello World ~w~n",[Name]).
大写开头的是变量Name,调用io模块的format方法输出,~w可以理解成占位符,将被实际Name取代,~n就是换行了。注意,函数定义完了要以句号.结束。然后执行c(helloWorld).编译源代码,执行:
9.内置的常用函数:
time()
length([1,2,3,4,5])
size({a,b,c})
atom_to_list(an_atom)
list_to_tuple([1,2,3,4])
integer_to_list(2234)
tuple_to_list({})
hd([1,2,3,4]) %输出1,也就是列表的head,类似Lisp的car
tl([1,2,3,4]) %输出[2,3,4],也就是列表的tail,类似List的cdr
10.常见Shell命令:
1)h(). 用来打印最近的20条历史命令
2)b(). 查看所有绑定的变量
3) f(). 取消(遗忘)所有绑定的变量。
4) f(Val). 取消指定的绑定变量
5) e(n). 执行第n条历史命令
6) e(-1). 执行上一条shell命令
11.又一个不知道怎么翻译的概念——Guard。翻译成约束?呵呵。用于限制变量的类型和范围,比如:
integer(X) - X 是整数
float(X) - X 是浮点数
atom(X) - X 是一个atom
tuple(X) - X 是一个元组
list(X) - X 是一个列表
length(X) == 3 - X 是一个长度为3的列表
size(X) == 2 - X 是一个长度为2的元组
X > Y + Z - X >Y+Z
X == Y - X 与Y相等
X =:= Y - X 全等于Y
(比如: 1 == 1.0 成功
1 =:= 1.0 失败)
为了方便比较,Erlang规定如下的比较顺序:
其中pid就是process的id。
12.忘了介绍apply函数,这个函数对于熟悉javascript的人来说很亲切,javascript实现mixin就得靠它,它的调用方式如下:
apply(Mod, Func, Args),三个参数分别是模块、函数以及参数列表,比如调用我们的第一个Erlang程序:
13.if和case语句,if语句的结构如下:
if
Guard1 ->
Sequence1 ;
Guard2 ->
Sequence2 ;
...
end
而case语句的结构如下:
Pattern1 [when Guard1] -> Seq1;
Pattern2 [when Guard2] -> Seq2;
PatternN [when GuardN] -> SeqN
end
if和case语句都有一个问题,就是当没有模式匹配或者Grard都是false的时候会导致error,这个问题case可以增加一个类似java中default的:
_ ->
true
end
通过_指代任意的Expr,返回true,而if可以这样:
true ->
true
end
一样的道理。case语句另一个需要注意的问题就是变量范围,每个case分支中定义的变量都将默认导出case语句,也就是在case语句结束后可以被引用,因此一个规则就是每个case分支定义的变量应该一致,不然算是非法的,编译器会给出警告,比如:
case g(X) of
true -> A = h(X), B = A + 7;
false -> B = 6
end,
h(A).
如果执行true分支,变量A和变量B都被定义,而如果执行的false分支,只有变量B被定义,可在case语句执行后,h(A)调用了变量A,这是不安全的,因为变量A完全可能没有被定义,编译器将给出警告
variable 'A' unsafe in 'case' (line 10)
14.给出一些稍微复杂的模型匹配例子,比如用于计算数字列表的和、平均值、长度、查找某元素是否在列表中,我们把这个模块定义为list:
-export([average/1,sum/1,len/1,double/1,member/2]).
average(X)->sum(X)/len(X).
sum([H|T]) when number(H)->H+sum(T);
sum([])->0.
len([_|T])->1+len(T);
len([])->0.
double([H|T]) -> [2*H|double(T)];
double([]) -> [].
member(H, [H|_]) -> true;
member(H, [_|T]) -> member(H, T);
member(_, []) -> false.
细细体会,利用递归来实现,比较有趣,这其实与Lisp中利用尾递归来实现迭代是一样的道理,[H|T]的形式类似Lisp中的car、cdr操作。_用于指代任意的变量,当我们只关注此处有变量,但并不关心变量的值的时候使用。用分号;来说明是同一个函数定义,只是不同的定义分支,通过模式匹配来决定调用哪个函数定义分支。
另一个例子,计算各种图形的面积,也是课程中给出的例子:
-export([factorial/1,area/1]).
factorial(0)->1;
factorial(N) when N>0->N*factorial(N-1).
%计算正方形面积,参数元组的第一个匹配square
area({square, Side}) ->
Side * Side;
%计算圆的面积,匹配circle
area({circle, Radius}) ->
% almost :-)
3 * Radius * Radius;
%计算三角形的面积,利用海伦公式,匹配triangle
area({triangle, A, B, C}) ->
S = (A + B + C)/2,
math:sqrt(S*(S-A)*(S-B)*(S-C));
%其他
area(Other) ->
{invalid_object, Other}.
执行一下看看:
{ok,mathStuff}
2> mathStuff:area({square,2}).
4
3> mathStuff:area({circle,2}).
12
4> mathStuff:area({triangle,2,3,4}).
2.90474
5> mathStuff:area({other,2,3,4}).
{invalid_object,{other,2,3,4}}
Erlang使用%开始单行注释。
from:http://www.blogjava.net/killme2008/archive/2007/06/13/123860.html
Erlang入门(一)的更多相关文章
- Erlang入门
Erlang简史(翻译) Erlang入门(二)—并发编程 Erlang入门(三)——分布式编程 Erlang入门(四)——错误处理和鲁棒性 Erlang入门(五)——补遗
- Erlang入门(五)——补遗
暂时搞不到<Programming Erlang>,最近就一直在看Erlang自带的例子和Reference Manual.基础语法方面有一些过去遗漏或者没有注意的,断断续续仅记于此. 1 ...
- Erlang入门(二)—并发编程
Erlang中的process——进程是轻量级的,并且进程间无共享.查了很多资料,似乎没人说清楚轻量级进程算是什么概念,继续查找中...闲话不提,进入并发编程的世界.本文算是学习笔记,也可以说是< ...
- Erlang入门(四)——错误处理和鲁棒性
去了趟福州,事情没搞定,托给同学帮忙处理了,回家休息了两天就来上班了.回家这几天最大的收获是第四次重读<深入Java虚拟机>,以前不大明了的章节豁然开朗,有种开窍的感觉,水到渠成,看来技术 ...
- Erlang入门(三)——分布式编程
明天要回家一个星期了,好好休息下.今天找到别人翻译的Erlang编程手册,值的好好读一遍. 所谓分布式的Erlang应用是运行在一系列Erlang节点组成的网络之上.这样的系统的性质与单一节点上 ...
- erlang入门之编译和运行
测试erlang脚本如下 -module(empty). -author("mmc"). %% API -export([test/1,test/0]). test()-> ...
- [Erlang 0126] 我们读过的Erlang论文
我在Erlang Resources 豆瓣小站上发起了一个征集活动 [链接] ,"[征集] 我们读过的Erlang论文",希望大家来参加.发起这样一个活动的目的是因为Erlang相 ...
- erlang文章博客推荐
博客排名不分先后. 诸霸,http://blog.yufeng.info/. 淘宝核心系统资深技术专家,真的是专家,了解erlang已不久局限于erlang,而且现在也一直在更新技术博文,和陈晧一样. ...
- Erlang分布式在linux和windows上的注意事项
没事做,就在两台机器间测试下Erlang分布式的例子,一个台是windowsXP,一台装的redHat9,没有详细的文档,自己摸索着搞成功了,记录下. 1.首先,分布式Erlang的实现提供了自有的安 ...
随机推荐
- 内核升级修复nfs
Not starting NFS kernel daemon: no support in current kernel. sudo gedit /etc/init.d/nfs-kernel-serv ...
- frame 之间访问
index.asp代码 <frameset rows="50,*,20" cols="*" frameborder="no" bord ...
- Mac OS X 10.10 Yosemite PHP 5.5.14 free type support fix
通过将php将至5.4来勉强支持freetype扩展,不推荐此方法 after upgrading to new Mac OS X Yosemite, i noticed that free type ...
- 微软职位内部推荐-Principal DEV Manager for Bing Client
微软近期Open的职位: Title: Principal DEV Manager for Bing ClientGroup: Search Technology Center Asia, BingW ...
- netty sample
http://netty.io/wiki/ https://github.com/netty/netty/tree/master/example/src/main/java/io/netty/exam ...
- CQRS学习——Storage实现(EF+Code First+DynamicReponsitory)[其四]
[这里是的实现,指的是针对各个数据访问框架的一个基础实现] 目标 定义仓储/QueryEntry的基本功能 实现仓储的基本功能,以利于复用 实现一些常用的功能 提供一些便利的功能 目标框架 博主使用的 ...
- [转载]jquery ajax/post/get 传参数给 mvc的action
jquery ajax/post/get 传参数给 mvc的action 1.ActionResult Test1 2.View Test1.aspx 3.ajax page 4.MetaO ...
- dijkstra,bellman-ford,floyd分析比较
http://www.cnblogs.com/mengxm-lincf/archive/2012/02/11/2346288.html 其实我一直存在疑惑是什么导致dijkstra不能处理负权图? 今 ...
- 软考类----编码、ASII码等
淘米2014实习生笔试,今年是淘米第一年招暑期实习生,笔试好大部分考的是软考的题目啊啊啊啊(劳资后悔当年没考软考刷加权),其他是浅而泛的风格,C++,SQL语句,数据结构(哈夫曼树,二叉查找树,栈后缀 ...
- php的redis 操作类,适用于单台或多台、多组redis服务器操作
redis 操作类,包括单台或多台.多组redis服务器操作,适用于业务复杂.高性能要求的 php web 应用. redis.php: <?php /* redis 操作类,适用于单台或多台. ...