3.3.12高阶函数
(1)将函数作为输入参数或返回值的函数,例如map
map(Fun, [H|T]) -> [Fun(H) | map(Fun, T)];
map(Fun, []) -> [].
eg:
map(fun(I) -> 2 *I end, [1,2,3,4]).
[2,4,6,8]
eg: c语言中的for循环
sum = 0;
for(int i = 0; i < max; i++)
{ sum += fun(i);}
没有for循环,自己构造for函数为:
for(I, Max, Fun, Sum) when I < Max ->
for(I+1, Max, Fun, Sum+F(I));
for(I, Max, Fun, Sum) ->
Sum.
使用for函数
Sum0 = 0.
Sum = for(0, Max, Fun, Sum0).
(2)构造新函数
比较难于理解,
eg:
1>Adder = fun(X) -> Fun(Y) -> X+Y end end.
2>Adder10 = Adder(10). //相当于 Adder10(Y)->10+Y
3>Adder10(5).
4>15
3.3.13表理解list comprehension
对某个列表list,进行计算,类似于foreach循环
[X || Qualifier1, Qualifier2,...]
X为表达式, Qualifier 为 Pattern <- ListExpr
eg:快速排序, ++为中缀添加运算符 ??
qsort([]) -> [];
qsort([Pivot|T]) ->
qsort([X||X<-T, X=< Pivot]) ++
[Pivot]++
qsort([X||X<-T,X>Pivot]).
eg:计算一个串的所有排列, X--Y:X中有,而Y没有的
perms([]) -> [[]];
perms(L) -> [[H|T] || H <- L, T <-perms(L--[H])]. ???
3.3.14 二进制数
用于高效IO操作
二进制和list转换:<<>> 和[]: list_to_binary/binary_to_list
二进制和项式,元组: <<>> 和{}:list_to_term/term_to_list
二进制合并 concat_binary
二进制切割 split_binary
eg:
B1=list_to_binary([1,2,3]).
=> <<1,2,3>>
B2=list_to_binary([4,5[6,7,8]]).
=> <<4,5,6,7,8>>
B3=concat_binary([B1,B2]).
=> <<1,2,3,4,5,6,7,8>>
split_binary(B3,4).
=> [<<1,2,3,4>>,<<5,6,7,8>>]
B=term_to_binary({hello, "joe"}).
=> <<131,104,.......>> //ASIIC码
binary_to_term(B).
=> {hello, "joe"}
3.3.15位语法
构造二进制数,和对二进制数进行匹配
二进制默认为8位,可以修改; /big/little改变"大头"和"小头"
eg: X1=1, Y2=255, Y3=256
<<X,Y2,Y3>>
=> <<1,255,0>> //Y3的256默认在8bit下已经溢出,
<<X,Y2,Y3:16>>
=> <<1,255,1,0>> //改为16位输出后,高8位的1输出,低8位仍0
<<X,Y2,Y3:32>>
=> <<1,255,1,0,0>>
<<256:32/big, 256:32/little>>
=> <<0,0,1,0, 0,1,0,0>>
二进制模式匹配
<<1:1,2:7>>
=> <<130>>
<<X:1,Y:7>> == <<130>>
=> X==1, Y ==2
3.3.16记录record
把名字和元组的具体元素关联,相当于struct,可以用来创建复杂的数据结构
-record(Name, {Key1=Value1,Key2=Value2...}).
eg:
-record(person, {firstName="",lastName="", age}).
定义后,可以创建实例
Person = #person{firstName="Rip, lastName="Van",age=111}.
同时可以模式匹配,
birthday(X=#person{age=N}) -> X#person{age=N+1}.
则X绑定了整个person字段,而N绑定了age字段
eg:
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属性。