Go 学习笔记3 - Map|Go主题月

563 阅读2分钟

1.map 概述

  • 类似其它语言中的哈希表或者字典,以 key-value 形式存储数据

  • key 必须是支持 ==!= 比较运算的类型,不可以是函数、map 或 slice

  • map 查找比线性搜索快很多,但比使用索引访问数据的类型慢100倍

  • 简单 map 的创建与使用

map 使用 make()创建,支持 := 这总简写方式

func main() {
	// 方式1:
	var m map[int]string
	m = map[int]string{}

	// 方式3:
	var b map[int]string = make(map[int]string)
  
	// 方式3:
	c := make(map[int]string)
	fmt.Println(m, b, c)
}

map 的使用:

赋值操作:

func main() {
	c := make(map[string]int)
	c["age"] = 18
}

从 map 中取值:

func main() {
  var age int
	d := map[string]int{"age": 18}
	age = d["age"] // 取值
}

注意:从 map 中获取一个不存在的 key 时,返回的时 value 对应的零值。所以此时无法判断 value 里的零值是不存在还是原来存入的就是零值。此时可以使用如下形式:

func main() {
	d := map[string]int{"age": 18}
	name, ok := d["name"] // 第二个参数返回一个 bool,为 true 代表 key 存在
	fmt.Println(name, ok) // 0 false
}

从 map 中删除一个 key 使用 delete(),如果删除的 key 不存在不会报错,但是无任何意义。

func main() {
  d := map[string]interface{}{"age": 18, "name": "张三"}
	delete(d, "name")
	fmt.Println(d)
	delete(d, "sex")
}

在函数间传递 map:

函数间传递 map 不会拷贝一个该 map 的副本,所以如果将 map 传递给一个函数,在函数内对 map 做了修改,会影响原来的 map。切记

func main() {
	d := map[string]interface{}{"age": 18, "name": "张三"}
	updateMap(d)
	fmt.Println(d)

}

func updateMap(m map[string]interface{}) {
	m["name"] = "李四"
}

输出:

map[age:18 name:李四]

复杂 map 与键值对操作:

切记 map 必须使用 make 初始化,否则使用时会导致 panic。

// 多层map嵌套注意必须为每一层map进行初始化操作
func main() {
    //复杂map
    var m map[int]map[int]string
    m = make(map[int]map[int]string)
    a, ok := m[2][1]
    if !ok {
        m[2] = make(map[int]string)
    }
    m[2][1] = "good"
    a, ok = m[2][1]
    fmt.Println(a, ok)
}

2.map 与 slice 的迭代操作

sm := make([]map[int]string, 5)
for i := range sm {
	sm[i] = make(map[int]string, 1)
	sm[i][1] = "ok"
	fmt.Println(sm[i])
}
fmt.Println(sm)

3.map 的间接排序

由于 map 的无序性,所以我们只能先把 map 的 key 取出放入一个 slice,然后对 slice 进行排序,最后通过 slice的 val 当做 map 的 key,有序的取出 map 里面的值,进行间接排序

func main() {
	m := map[int]string{5: "a", 3: "b", 1: "c", 4: "d", 2: "e"}

	s := make([]int, len(m))
	i := 0
	for k, _ := range m {
		s[i] = k
		i++
	}
	sort.Ints(s)
	for _, v := range s {
		fmt.Println(v, m[v])
	}
}