Erlang(三)记录和映射组

元组用于保存固定数量的元素,列表用于保存可变数量的元素

记录和映射组

记录是元组的另一种形式,可以给元组的每个元素关联一个名称。

映射组是键值对的关联性集合,键是任意的Erlang类型。

记录,通过记录命名元组里的项

.record(Name, {
    key1 = default1,
    key2 = default2,
    key3 = default3.
    ...     
}).

shell中用rr

Name是记录名,key是字段原子,记录可带默认值,创建记录没有指定值,就使用默认值。

record.hrl

-record(todo,{status = reminder, who = joe, text}).
rr(record.hrl).
#todo{}.
X1 = #todo{status = urgent, text="fix errata in book"}.
X2 = X1#todo{status = done}.

X2复制记录,生成原始记录的副本,原记录没有变化。

提取记录字段

#todo{who = W, text = T} = X2.
W.
T.

左侧记录模式匹配成功,变量会变成绑定字段

X2#todo.text

记录的单个字段,可以用点语法获取

在函数里模式匹配记录

clear_status(#todo{status=S, who=W} = R) -> R#todo(status=finished).
%%value in record
%%R是整个记录

匹配摸个类型的记录

do_somethine(X) when_is_record(X, todo) -> ...

todo类型匹配成功执行

记录是元组的另一种形式

X2.
rf(todo).
X2.

rf命令使shell忘了todo的定义,打印时显示为元组。

###映射组,关联式键值存储

语法:

#{key1 Op val1, key2 Op val2}.

散列符号#之后没有记录名,Op为=>或者:=

键和值可以是任何有效的erlang类型

F1 = #{a=>1,b=>2}.
Facts = #{ {wife,fred}=>"sue",{age,fred}=>45 }.
F2 = #{b=>2, a=>1}.
F1 = F2.

k=>v将现有的键k更新为新值v,给映射组添加新的k-v

k:=v将现有的键k更新为新值v,如果被更新的映射组不包含键k,操作会失败(共享相同的键操作符,效率更高,可以抛出错误)

模式匹配映射组字段

Henry8 = #{class=>king, born=>1491, died=>1547}.
#{born=>B} = Henry.
B.
1491

操作映射组的内置函数

maps:new()->#{}
erlang:is_map(M)->bool
maps:to_list(M)->[{k1,v1},...]
maps:from_list([{k1,v1},...])->M
maps:map_size(M)->num
maps:is_key(key,M)->bool
maps:get(key,M)->val
maps:find(key,M)->{ok,value} | error
maps:keys(M)->[key1,key2,..]
maps:remove(key,M)->M1
maps:without([key1,key2,...],M)->M1
maps:difference(M1,M2)->M3

M3是M1的复制,移除了M2元素具有相同键的元素

映射组的比较

先比较大小,再按键排序,比较键和值

maps:to_json(M)->bin
maps:from_json(Bin)->M
maps:safe_from_json(Bin)->M
erlang9