Map之类的一些KV存储数据集合之类,在业务中使用蛮广泛的,其中,在CodeReview中发现,希望用map存储数据,但又能有序取出数据,以及并发安全map的需求出现的比较多,而各自的代码实现都有点绕,其实有更好的封装,大家直接拿过来用就好了。
给几个例子:
package main
/*
几个集合的小例子
Author: XCL
Date: 2017-6-25
*/
import (
"fmt"
"sort"
"sync"
"utils"
"golang.org/x/sync/syncmap"
)
var (
data = []string{"bb", "aa", "1d", "ee", "cc"}
)
func main() {
fmt.Println("---------------------------------")
fmt.Println(" 有序集合(map + sort) ")
fmt.Println("---------------------------------")
map1()
fmt.Println("---------------------------------")
fmt.Println(" 有序集合(左倾红黑树) ")
fmt.Println("---------------------------------")
map2()
fmt.Println("---------------------------------")
fmt.Println(" 并发map(golang.org/x/sync/syncmap) ")
fmt.Println("---------------------------------")
map3()
}
func map1() {
// map = c++ unordered_map = 哈希表
m := make(map[string]string)
for _, v := range data {
m[v] = v
}
keys := make([]string, 0, len(m))
for _, v := range m {
keys = append(keys, v)
}
sort.Strings(keys)
for _, k := range keys {
fmt.Println("map1:", k, " => ", m[k])
}
}
func map2() {
// <<Programming in Go>>中的omap = c++ map = 红黑树
// C++ http://www.teachsolaisgames.com/articles/balanced_left_leaning.html
m := utils.NewCaseFoldedKeyed()
for _, v := range data {
m.Insert(v, v)
}
m.Do(func(k, v interface{}) {
fmt.Println("map2:", k, " => ", v)
})
}
func map3() {
// 并发map
// golang.org/x/sync/syncmap
m := new(syncmap.Map)
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func(v int) {
defer wg.Done()
m.Store(v, v*10)
}(i)
}
wg.Wait()
m.Range(func(ki, vi interface{}) bool {
k, v := ki.(int), vi.(int)
fmt.Println("map3.range:", k, " => ", v)
return true
})
}
/*
输出:
---------------------------------
有序集合(map + sort)
---------------------------------
map1: 1d => 1d
map1: aa => aa
map1: bb => bb
map1: cc => cc
map1: ee => ee
---------------------------------
有序集合(左倾红黑树)
---------------------------------
map2: 1d => 1d
map2: aa => aa
map2: bb => bb
map2: cc => cc
map2: ee => ee
---------------------------------
并发map(golang.org/x/sync/syncmap)
---------------------------------
map3.range: 1 => 10
map3.range: 0 => 0
map3.range: 5 => 50
map3.range: 8 => 80
map3.range: 3 => 30
map3.range: 2 => 20
map3.range: 4 => 40
map3.range: 7 => 70
map3.range: 6 => 60
map3.range: 9 => 90
*/
上面列了最简单的用法,当然还有更多用法可以去看代码实现。