# erlang 数据结构 --maps

xiaoxiao2021-02-28  34

### 1. 今天是maps

1.1. key-value 数据结构 1.2. 更好的模式匹配

### 2.操作：

#### 2.0 格式

1> F = #{a => 1, b => 2}. #{a => 1,b => 2}

#### 2.1. 更新key-value

=> 如果原本有key， 则更新, 如果没有key，就插入key-value; := 更新已有的key的value，如果原来没有key，就报错

3> F1 = F#{a => 2}. #{a => 2,b => 2} 4> F2 = F#{c => 3}. #{a => 1,b => 2,c => 3} 5> F3 = F#{a := 1}. #{a => 1,b => 2} 8> F5 = F#{c := 2}. ** exception error: {badkey,c} in function maps:update/3 called as maps:update(c,2,#{a => 1,b => 2}) in call from erl_eval:'-expr/5-fun-0-'/2 (erl_eval.erl, line 255) in call from lists:foldl/3 (lists.erl, line 1263)

#### 2.2 模式匹配

maps 记录频率

freq(Is) -> freq(Is, #{}). freq([I|Is], #{I := C} = M) -> freq(Is, M#{ I := C + 1}); freq([I|Is], M) -> freq(Is, M#{ I => 1 }); freq([], M) -> maps:to_list(M).

gb_trees用于比较的等效代码：

freq(Is) -> freq(Is, gb_trees:empty()). freq([I|Is], T) -> case gb_trees:lookup(I, T) of none -> freq(Is, gb_trees:enter(I, 1), T); {value, V} -> freq(Is, gb_trees:enter(I, V + 1, T)) end; freq([], T) -> gb_trees:to_list(T).

### 3 内存实现

eep中对内存的描述为 Data layout: map_ext |———————————–

14116SizeKeysValues

erl_map.h 中对内存实现的描述

/* map node * * ----------- * Eterm THING * Uint size * Eterm Keys -> {K1, K2, K3, ..., Kn} where n = size * ---- * Eterm V1 * ... * Eterm Vn, where n = size * ----------- */ /* the head-node is a bitmap or array with an untagged size */

maps 为boxed 对象， 开头为boxed对象的必要tag，接下来为size， 之后Eterm为keys（ 指向了一段连续的内存key tuple）， 之后为value tuple 我们可以从源码 erl_map.c erts_maps_get/2 实现中验证这种看法， 这个函数的目的是得到key对应的value

const Eterm * erts_maps_get(Eterm key, Eterm map) { Uint32 hx; if (is_flatmap(map)) { Eterm *ks, *vs; flatmap_t *mp; Uint n, i; mp = (flatmap_t *)flatmap_val(map); n = flatmap_get_size(mp); if (n == 0) { return NULL; } ks = (Eterm *)tuple_val(mp->keys) + 1; vs = flatmap_get_values(mp); if (is_immed(key)) { for (i = 0; i < n; i++) { if (ks[i] == key) { return &vs[i]; } } } else { for (i = 0; i < n; i++) { if (EQ(ks[i], key)) { return &vs[i]; } } } return NULL; } ASSERT(is_hashmap(map)); hx = hashmap_make_hash(key); return erts_hashmap_get(hx, key, map); }

### 4.使用场景

#### 4.1. 替换record ，

No more need for records

### 6. 引用

6.1. yufeng Erlang 新数据类型Map的定位和性能 6.2. siyao Erlang 的新数据结构 map 浅析 6.3. 坚强2002 当我们谈论Erlang Maps时,我们谈论什么 Part 1 and 当我们谈论Erlang Maps时,我们谈论什么 Part 2 6.4. learnyousomeerlang