Erlang入门(五)——补遗

时搞不到《Programming Erlang》,最近就一直在看Erlang自带的例子和Reference Manual。基础语法方面有一些过去遗漏或者没有注意的,断断续续仅记于此。

1。Erlang的保留字有:

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
时间: 2024-09-10 08:36:59

Erlang入门(五)——补遗的相关文章

Windows 8风格应用开发入门 五 ListView数据控件

什么是ListView数据控件? 1) ListView数据控件用来显示数据集合. 2) 继承自ItemsControl. 3) 大多数情况是纵向显示数据,显示的数据通常是排序过的. 4) 在切换到Snap View(贴靠视图)时,通常使用ListView显示数据集合. 开发入门 五 ListView数据控件-vba listview 控件"> 如何构建ListView数据控件? 首先我们需要了解一下ListView控件中一些重要属性和事件: 1) IsItemClickEnabled属性

AppleWatch开发入门五——菜单控件的使用

AppleWatch开发入门五--菜单控件的使用 一.简介         菜单也是WatchOS中一个重要的交互方式,限于Watch的屏幕尺寸,若将所有用户交互控件都紧密的排列进展示的UI中,那样难免会使用户操作困难,也会影响界面布局的简洁美观.因此,WatchOS的菜单机制是一层覆盖在屏幕上的交互界面,有如下的特点: 1.菜单是内置于InterfaceController中的,不需显式处理,只需对齐菜单项进行添加设置. 2.菜单最多可以容乃四个选项按钮. 3.通过重按可以呼出和隐藏菜单. 二

DevExpress XtraReports 入门五 创建交叉表报表

原文:DevExpress XtraReports 入门五 创建交叉表报表 本文只是为了帮助初次接触或是需要DevExpress XtraReports报表的人群使用的,为了帮助更多的人不会像我这样浪费时间才写的这篇文章,高手不想的看请路过 本文内容来DevExpress XtraReports帮助文档,如看过类似的请略过. 废话少说 开始正事 一.准备数据绑定 XRPivotGrid 控件 启动 MS Visual Studio (2005.2008 或 2010),并且新建一个或者打开一个现

Thinkphp入门 五 —模型 (49)

原文:Thinkphp入门 五 -模型 (49) [数据库操作model模型] model  模型  数据库操作 tp框架主要设计模式:MVC C:controller   控制器   shop/Lib/Action/具体控制器 V:view       视图     shop/Tpl/分组/模板文件 M:model      数据模型  shop/Lib/Model/具体模型   [创建模型] 创建的原则:一个数据表对应一个数据模型 创建模型: 当出现以下信息,说明我们的数据库没有配置用户名和

Erlang入门(二)—并发编程

Erlang中的process--进程是轻量级的,并且进程间无共享.查了很多资料,似乎没人说清楚轻量级进程算是什么概念,继续查找中...闲话不提,进入并发编程的世界.本文算是学习笔记,也可以说是<Concurrent Programming in ERLANG>第五张的简略翻译. 1.进程的创建     进程是一种自包含的.分隔的计算单元,并与其他进程并发运行在系统中,在进程间并没有一个继承体系,当然,应用开发者可以设计这样一个继承体系.     进程的创建使用如下语法: Pid = spaw

Erlang入门(四)——错误处理和鲁棒性

    去了趟福州,事情没搞定,托给同学帮忙处理了,回家休息了两天就来上班了.回家这几天最大的收获是第四次重读<深入Java虚拟机>,以前不大明了的章节豁然开朗,有种开窍的感觉,水到渠成,看来技术的学习还是急不来.     闲话不提,继续Erlang的学习,上次学习到分布式编程的章节,剩下三章分别是错误处理.构造健壮的系统和杂项,错误处理和构造健壮的系统今天一起读了,仅摘记下.     任何一门语言都有自己的错误处理机制,Erlang也不例外,语法错误编译器可以帮你指出,而逻辑错误和运行时错误

Kinect for Windows SDK开发入门(五)景深数据处理 下

1. 简单的景深影像处理 在上篇文章中,我们讨论了如何获取像素点的深度值以及如何根据深度值产生影像.在之前的例子中,我们过滤掉了阈值之外的点.这就是一种简单的图像处理,叫阈值处理.使用的阈值方法虽然有点粗糙,但是有用.更好的方法是利用机器学习来从每一帧影像数据中计算出阈值.Kinect深度值最大为4096mm,0值通常表示深度值不能确定,一般应该将0值过滤掉.微软建议在开发中使用1220mm(4')~3810mm(12.5')范围内的值.在进行其他深度图像处理之前,应该使用阈值方法过滤深度数据至

AJAX入门---五步使用XMLHttpRequest对象

         XMLHttpRequest简介:          XMLHttpRequest对象可以在不向服务器提交整个页面的情况下,实现局部更新网页.当页面全部加载完毕后,客户端通过该对象向服务器请求数据,服务器端接受数据并处理后,向客户端反馈数据.XMLHttpRequest 对象提供了对 HTTP 协议的完全的访问,包括做出 POST 和 HEAD 请求以及普通的 GET 请求的能力.XMLHttpRequest 可以同步或异步返回 Web 服务器的响应,并且能以文本或者一个 DO

Erlang入门(三)——分布式编程

  明天要回家一个星期了,好好休息下.今天找到别人翻译的Erlang编程手册,值的好好读一遍.     所谓分布式的Erlang应用是运行在一系列Erlang节点组成的网络之上.这样的系统的性质与单一节点上的Erlang系统并没有什么不同.分布式这是个"大词",Erlang从语言原生角度支持分布式编程,相比于java简单不少. 一.分布式机制 下列的BIFs是用于分布式编程:spawn(Node, Mod, Func, Args) 启动远程节点的一个进程 spawn_link(Node