跳到主要内容

go map类型

hash table 是计算机科学中非常重要的数据结构,它的特性有很多,其中快速查询是最常使用的特性。go 提供了 map 类型,它底层是 hash table

1. 定义

map 定义形式如下,它分为键(KeyType)和值(ValueType),下面例子中mKeyTypestring,ValueTypeint

map[KeyType]ValueType
var m map[string]int

map 常用的使用场景是获取 key 对应的值,这就需要判断 map 里面的 key 与用户指定的 key 是否相等,所以 map 要求 KeyType可比较的。slicemap和函数无法作为 key

m["route"] = 66 //将route这个key对应的值设置为66

i := m["route"] //获取route这个key对应的值,并将他赋给i

2. 常用操作

2.1 初始化

 仅声明 map 不初始化,map 的值为nil。当读 nil map 时和读一个空 map 一样,但是写 nil map 时,会抛出异常。

package main

import (
"fmt"
)

func main() {

var m map[string]int
t, ok := m["abc"]

fmt.Printf("\n t is %d, ok is %t", t, ok)

m["def"] = 1
}

提示

 当 key 对应的 value 不存在时,map 会返回值类型对应的0值。上面例子里,int类型的0值为0。

map 的初始化方式有两种:1. 调用内建函数 make。2. 使用 map literal

package main

func main() {

var a map[string]int = make(map[string]int)
var b map[string]int = map[string]int{
"abc": 1,
"def": 2,
}

}

2.2 函数调用

 内建函数len可以返回 map 里面的条目数;delete方法可以删除 map 里的某一个 key;判断 key 是否存在可以使用二目赋值符;for-range可以遍历 map 里的键值对。

n := len(m) //获取map里的条目数

delete(m, "route") //删除route对应的值

i, ok := m["route"] //i表示route对应的值,ok表示route是否存在。

for key, value := range m {
fmt.Println("Key:", key, "Value:", value)
}
//遍历m

2.3 值为空接口

空接口类型用interface{}表示,所有类型都实现了空接口。如果 map 的值类型为interface{},意味着值可以是任意类型。

package main

import (
"fmt"
)

func main() {

type FuncType func(s string) string

var c FuncType = func(s string) string {
return s + "funType"
}

d := func(s string) string {
return s + "sfunc"
}

var a map[string]interface{} = map[string]interface{}{
"a": 1,
"b": "kkk",
"c": c,
"d": d,
}

for k, v := range a {
switch vType := v.(type) {
case int:
fmt.Printf("\nkey is %s and value is int %d", k, vType)
case string:
fmt.Printf("\nkey is %s and value is int %s", k, vType)
case FuncType:
fmt.Printf("\nkey is %s and value is int %s", k, vType(k))
case func(s string) string:
fmt.Printf("\nkey is %s and value is int %s", k, vType(k))
}
}

}

2.4 并发访问

map 不是并发安全的,如果在并发的 goroutines 里访问 map 需要进行加锁。例如:

var counter = struct{
sync.RWMutex
m map[string]int
}{m: make(map[string]int)}

counter.RLock() //promoted fields
n := counter.m["some_key"]
counter.RUnlock() //promoted fields
fmt.Println("some_key:", n)
提示

 关于 promoted fields 可以参考go 结构体


  1. Go maps in action

署名-非商业性使用-禁止演绎 4.0 国际