一、record和maps的使用场景
记录其实就是元组的另一种形式,因此它的储存和性能特性与元组是一样的,而映射组因为有键的存在,所以他比元组占用更多的内存查询起来也慢,但是它更灵活
1.记录的使用场景
- 当你可以预先确定且数量固定的原子来表示数据时;(因为元组一旦定义,他元素的数量是确定的)
- 当记录里的元素数量和元素名称不会随时间而改变时;(使用记录后,就像maps一样拥有键,如果元素的名称改变的话,记录内的键是不会变的)
- 当储存空间是个问题,典型的案例是你有一大堆元组,并且每个元组都有一样的结构。
2.映射组的使用场景
- 当键不能预先知道时用来表示键-值数据结构(
键不指定值的类型 你可以用任何东西当值 可以是基本数据类型也可以是对象 可以通过键来获取值 但不能通过值来获取键) - 当存在大量不同的键时用来表示数据
- 当方便使用很重要而效率无关紧要时
- 用作“自解释型”的数据结构,也就是说,用户容易从键名猜出键值的含义
- 用来表示键-值解析树,例如XML或配置文件;
- 用Json来和其他编程语言通信。
二、通过记录命名元组里的元素
在源代码里,使用
-record(Name,{
key1 = Default1,
key2,
...
keyN
})
源码中,Name必须是原子类型,key1...keyN是用来命名的原子类型,而Default1则是我们给这个位置的元素赋予的默认值,当定义带记录的元组时使用了没绑定值的变量时或者省略时,会使用这个默认值,如果没有设置默认值,则默认值是undefined,当有很多module共同用到一个record时,为了方便可以把record的定义放在.hrl中,这个类似于C++的h头文件,在shell中rr可以读取这条记录,rf可以除去这个记录
创建和更新记录、提取记录字段、匹配记录
-record(todo,{
name = "nobody",
age = 18,
sex
}).
test()->
Record1=#todo{sex="Male"},
Record2=Record1#todo{name="Loop"},
Record3=Record2#todo{age=21},
#todo{name=Name,age=Age,sex=Sex}=Record3,
io:format("Name_Is:~p Age_Is:~p Sex_Is:~p~n",[Name,Age,Sex]).
三、映射组:关联式键-值储存
1.映射组语法
{Key1 op Val1,.....,KeyN,ValN}.
这个语法和记录相似,知识没有了记录名,op有两个
- =>这个操作符当键不存在时可以创建一个键值关联,当键存在时直接更新这个键的值
- :=这个操作符仅当键存在时可以用否则GG,模式匹配时也只能用:=
- Key可以是任何有效的Erlang数据类型(前提是绑定了)
- 映射组在系统内部是有顺序的,按照键排序
- 更新时和记录差不多 NewMap=OldMap#{Key2Up=>Value2Up}.
2.映射组的BIF
-
maps:new()->#{}
返回一个新的空映射组 -
erlang:is_map(M)->bool()
判断是否为Map -
maps:to_list(M)->[{Key,Val}]
-
maps:from_list([{Key,Val}])->M
-
maps:size(M)->integer()
-
maps:is_key(Key,Map)->bool().
-
maps:get(Key,Map)->Val
-
maps:find(Key,Map)->{ok,Value}|error
-
maps:keys(Map)->[Key1,...,KeyN]
-
maps:remove(Key,M)->M_new.
-
maps:without([Key1,....,KeyN],M)->M1
返回一个没有[Key1,...,KeyN]的新map -
maps:difference(M1,M2)->M3
M3是M1的复制,但是移除了M2中共同的键
就像maps:without(maps:keys(M2),M1).
网友评论