Erlang顺序编程(二)

case/if语法:
case表达式语法:

case Expression of
Pattern1 [when Guard1] ->Expr_seq1;
Pattern2 [when Guard2] ->Expr_seq2;

end.


if表达式语法:

if
Guard1 -> Expr_seq1;
Guard2 -> Expr_seq2;

end


创建一个列表最有效的方法就是把元素加在一个现有列表的头部。
发转一个列表:lists:reverse(L).

例子:将一个整数列表分解为偶数列表和基数列表
方法一:采用列表解析方式实现

-module(odd_even).
-export([odd/1]).
-export([even/1]).
odd(L) ->
[X || X <- L,(X rem 2) =:= 1].
even(L) ->
[X || X <- L,(X rem 2) =:= 0].


方法二:采用case...end实现:

-module(odd_even).
-export([odd/1]).
-export([even/1]).
odd([H|T]) ->
case (H rem 2) of
1 -> [H|odd(T)];
0 -> odd(T)
end;
odd([]) ->[].
even([H|T]) ->
case (H rem 2) of
0 -> [H|even(T)];
1 -> even(T)
end;
even([]) ->[].


异常:一个函数可能成功返回一个值,也可能出现错误,当出现一个错误的时候,系统抛出一个异常。
遇到系统内部错误或在代码中显示的调用throw(Exception),exit(Exception),erlang:error(Exception),系统会抛出异常。显示的产生一个错误。
exit(Why):这个函数用来终止当前进程,如果这个异常没有捕获,那么系统会向所有与当前进程相链接的进程广播{'exit',pid,Why}消息。
throw(Why):这个函数用来抛出一个调用者可能会捕获的异常,比如一个数除以0.可以将这个调用放在try...catch表达式中进行对错误的处理。
erlang:error(Why):这个函数用于抛出“崩溃错误”,这些异常应该是调用者不去处理的致命错误。

try..catch:
语法:

try FuncOrExpressionSequence of
Pattern1 [when Guard1] -> Expression1;
Pattern2 [when Guard2] -> Expression2;

catch
ExceptionType:ExPattern1 [when ExGuard1] -> ExExpression1;
ExceptionType:ExPattern2[when ExGuard2 -> ExExpression2;
after
AfterExpressions
end

erlang中任何东西都是表达式,所有的表达式都有值,所以,try...end也是有值的。
after后面的代码是做清理工作。
例子:

-module(exception).
-export([demo1/0]).

generate_exception(1) -> a;
generate_exception(2) -> throw(a);
generate_exception(3) -> exit(a);
generate_exception(4) -> {'EXIT',a};
generate_exception(5) -> erlang:error(a).

demo1() ->
[catcher(I)||I<-[1,2,3,4,5]].
catcher(N) ->
try generate_exception(N) of
Val -> {N,normal,Val}
catch
throw:X -> {N,caught,thrown,X};
exit:X -> {N,caught,exited,X};
error:X -> {N,caught,error,X}
end.


捕获所有可能的异常:_:_ -> ...Code to handle all

当出现异常的之后,可以通过调用erlang:get_stacktrace()来查看栈的跟踪信息。

BIF内置函数:(详情参考官方文档)

erlang中可以使用一种叫做二进制(binary)数据的结构来存储大量的原始数据,二进制数据在书写或打印的时候,以整数或字符串的形式出现,两边分别用<<>>括起来,例如:

<<5,10,20>>.
<<”hello”>>.

在二进制中用到整数,每一个必须在0-255之间。
list_to_binary(L):把列表L中的数据转换为二进制数据。
term_to_binary(Term):把任意的erlang值转换为二进制数。
binary_to_term(Bin):和term_to_binary(T)相反。
split_binary(B,Pos):在Pos指定的位置把二进制数据B分隔为两个部分。
size(Bin):返回二进制数据的字节长度。

比特语法:比特语法是模式匹配的一种扩展。常用于对二进制数据的封包和解包。
假定有三个变量X,Y,Z,希望把他们封装在一个16bit字节的内存区域。也就是变量M中。

M=<<X:3,Y:7,Z:6>>.


16bit色彩的封包和解包:
封包:

Red = 2.
Green = 61.
Blue = 20.
Mem = <<Red:5,Green:6,Blue:5>>.

解包:

<<R1:5,G1:6,B1:5>> = Mem.
//R1:2,G1:61,B1:20


用户定义属性:

-SomeTag(Value)

SomeTag必须是原子,Value必须是一个文字向。

块表达式:

Begin
Expr1,

ExprN
End

可以使用块表达式把一串表达式组织成一个类似子句的实体,begin...end块的值就是最后一个表达式的值。

布尔表达式:
not B1:逻辑非
B1 and B2:逻辑与
B1 or B2:逻辑或

短路布尔表达式
Expre1 orelse Expre2
首先求值的是表达式Expre1。如果运算结果为true,那么Expre2就不会被求值。
Expre1 andalsoExpre2
首先求值的是表达式Expre1,如果为false,那么Expre2就不会被求值。

包含文件:
-include(filename)
可以是扩展名为.hrl的包含文件,包含文件通常包含了记录的定义。

列表操作符++和--:
A++B意味着把A和B加起来。
A—B以为着从列表A中删除列表B。删除的意思是B中的所有元素都要从A中删除。

宏:
-define(Constant,Replacement).
-define(Func(Var1,Var2,…,Var),Replacement).
当erlang预处理器epp遇到形如?MacroName的表达式时,这个宏就会被预处理器扩展,在宏定义处出现的变量会匹配到宏调用处的完整形式。
系统预定义宏:
?FILE扩展为当前文件名。
?MODULE扩展为当前模块名。
?LINE扩展为当前行号。
在一个宏内部,还支持流程指令:
-undef(Macro):取消Macro的定义,在这个语句之后不能在调用这个宏。
-ifdef(Macro):只有Macro被定义之后,才对该行以下的代码进行运算。
-ifndef(Macro):只有在没有定义Macro的情况下,才对该行以下的代码进行运算。
-else:只能在ifdef()或ifndef()之后出现,如果条件为false,那么该语句后的代码才会执行。
-endif:标记ifdef或ifndef语句的结束。
例子:

-module(define).
-export([test1/0]).

-ifdef(debug).
-define(Trace(X), io:format("Trace ~p:~p ~p~n",[?MODULE,?LINE,X])).
-else.
-define(Trace(X),void).
-endif.

test1() -> loop(5).

loop(0) ->
void;
loop(N) ->
?Trace(N),
loop(N-1).

Io:format(String,[Args]):会根据String中的格式信息在Erlang shell中打印[Args]中的变量。格式化代码具有一个前缀(~),~p是完整打印的缩写,~n是产生一个新行。

这段代码在编译时需要开启或者关闭trace宏,{d,debug}把调试标志设为true以便在宏定义的-ifdef(debug)片段中能被识别,当关闭这个宏时,trace宏就被扩展为原子void.

进程字典:
erlang中每一个进程都有自己的私有数据存储,称为进程字典。进程字典由一系列key-value组成。一个key对应一个value.
put(key,value) -> OldValue|undefined.
get(key) -> Value|undefined
get() -> [{key,value}...]
get_keys(value) -> [key]
erase(key) -> value|undefined,最后删除这对key-value.
erase() -> [{key,value}...] 清空进程字典。

引用:引用是一个全局唯一的erlang值,使用erlang:make_ref()来创建引用。

比较表达式:
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。
为了进行比较,Erlang按照下面的方式为所有类型都定义了大小比较的顺序。
Number<atom<reference<fun<port<pid<tuple<list<binary.
说明:数值(任何值)总比原子小。
如果参数为数值,那么所有的比较操作符,除=:=和=/=之外,都遵循以下规则:
1.如果一个参数为整型,一个为浮点型,那么整型需要在比较之前转换为浮点型。
2.如果两个参数都是整型或者浮点型,那么参数无须转换,以原来类型比较。
==仅仅适用于浮点数和整数的比较。

为文件加载器设定搜索路径:
可以使用code:get_path()来查看当前加载路径的值。
code:add_patha(Dir) -> true|{error,bad_directory} 在加载路径开头增加一个新目录。
code:add_pathz(Dir) -> true|{error,bad_directory} 在加载路径末尾增加一个新目录。
code:all_loaded():返回一个所有被加载的module列表。
code:clash():查看出错的module.

查看系统的home目录:init:get_argument(home).
查看系统内存:erlang:memory(total).

-compile(export_all):特别声明,它告诉编译器把模块中每个函数都导出。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值