golang 字典map

字典map

哈希表是一种巧妙并且实用的数据结构,它是一个无序的key/value对的集合。在Go语言中,一个map就是一个哈希表的引用,map类型可以写为map[K]V, 其中K和V分别对应key和value。


创建空map的方式:

var a = make(map[string]int)
var b = map[string]int{}

用map字面值的语法创建map:

ages := map[string]int{
    "alice": 31,
    "charlie": 34,
}

// 2个效果等同
ages := make(map[string]int)
ages["alice"] = 31
ages["charlie"] = 34

使用内置的delete函数可以删除元素:

delete(ages, "alice")

如果一个map查找失败将返回value类型对应的零值:

fmt.Println(ages["zzz"]) //0

x += y 和 x++ 等简短赋值语法也可以用在map上:

ages["bob"] = ages["bob"] + 1
ages["bob"] += 1
ages["bob"]++

map中的元素并不是一个变量, 因此我们不能对map的元素进行取址操作,禁止对map元素取址的原因是map可能随着元素数量的增长而重新分配更大的内存空间, 从而可能导致之前的地址无效。

map类型的零值是nil, 也就是没有引用任何哈希表:

var c map[string]int
fmt.Println(c == nil) // "true"
fmt.Println(len(ages) == 0)

查找一个key是否存在,因为如果key不存在, 直接读取将得到value对应类型的零值,所以我们可以这样做:

age, ok := ages["bob"]
if !ok { 
    /* "bob" is not a key in this map; age == 0. */ 
}

// 你会经常看到将这两个结合起来使用
if age, ok := ages["bob"]; !ok { /* ... */ }


if age, ok := ages["zhexiao"]; !ok{
    fmt.Println("没找到")
}else{
    fmt.Println(age)
}

Map的value类型也可以是一个聚合类型, 比如是一个map或slice:

var graph = make(map[string]map[string]bool)

// demo
var a = make(map[string]map[int]string)
func main() {
    b := make(map[int]string)
    b[123] = "home"

    a["zhexiao"] =  b
    fmt.Println(a["zhexiao"][123])
}

有时候需要一个map或set的key是slice类型,但是map的key必须是可比较的类型,明显slice类型是不可比较的。但是我们可以通过两个步骤绕过这个限制:
1. 定义一个辅助函数k, 将map的key从slice类型转为string类型
2. 创建一个map,key为string类型的,每次对map操作时先用辅助函数k将slice转为string类型

var m = make(map[string]int)

func k(list []string) string {
    return fmt.Sprintf("%q", list)
}

func add(list []string) {
    m[k(list)]++
}

func count(list []string) int {
    return m[k(list)]
}

func main() {
    a := []string{"zhe", "xiao"}
    add(a)
    add(a)
    add(a)
    fmt.Println(count(a)) //3
    fmt.Println(m)  //map[["zhe" "xiao"]:3]
    fmt.Println(m["[\"zhe\" \"xiao\"]"])    //3
}

猜你喜欢

转载自blog.csdn.net/andybegin/article/details/80942398