[Golang] 容器

当然了,这里的容器不是CNI之类的运行容器,而是指Golang中存储和组织数据的方式。

1.并发安全的sync.map及其Range()

在golang中,常用test := make(map[string]int)的形式使用映射容器map,当然也可以直接在声明时填充内容:

1
2
3
4
5
m := map[string]int{
"w": 1,
"s": 2,
"a": 3,
}

清空map的唯一方法:重新make一个新的map。
但并发的map读写中会出现竞态问题,由sync包提供并发安全的map结构,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package main

import (
"fmt"
"sync"
)

func main() {
var scene sync.Map
scene.Store("greece", 97)
scene.Store("london", 100)
scene.Store("egypt", 200)

fmt.Println(scene.Load("london"))
scene.Delete("london")
scene.Range(func(k, v interface{}) bool {
fmt.Println("iterate:", k, v)
return true
})
}

代码输出如下:

100 true
iterate: egypt 200
iterate: greece 97

在sync.Map中,Store表示存储,Load表示获取,Delete表示删除。
比较有趣的是Range的使用,Range配合一个回调函数进行遍历操作,通过回调函数返回内部便利出来的值。Range参数接收到true时,继续迭代遍历,返回false时,终止迭代遍历。
Range()方法可以遍历sync.Map,遍历需要提供一个匿名函数,参数为k、v,类型为interface{},每次Range()在遍历一个元素时,都会调用这个匿名函数把结果返回。
当然,sync.Map为了保证并发安全有一些性能损失,因此在非并发情况下,使用map相比使用sync.Map会有更好的性能。