Skip to content

Map

Map的定义

map是 Go 语言的内置类型,它将一个值与一个键关联起来。可以使用相应的键检索值。

map是一种无序的键值对的集合。map最重要的一点是通过 key 来快速检索数据,key 类似于索引,指向数据的值。

map是一种集合,所以我们可以像迭代数组和切片那样迭代它。map是无序的,我们无法决定它的返回顺序,这是因为map是使用 hash 表来实现的,也是引用类型。

语法格式

go
var 变量名 map[键类型]值类型
go
变量名 = make(map[键类型]值类型)
go
变量名 := map[键类型]值类型{
    key1: value1,
    key2: value2,
    ...,
}

示例

go
package main

import "fmt"

func main() {
	// 定义一个map
	var m1 map[int]string
	fmt.Printf("m的类型:%T\n", m1)
	fmt.Printf("m是否为nil:%t\n", m1 == nil) // true
}
go
package main

import (
	"fmt"
)

func main() {
	// make函数创建map
	m1 := make(map[int]string)
	fmt.Printf("m的类型:%T\n", m1)
	fmt.Printf("m是否为nil:%t\n", m1 == nil) // false

	m2 := make(map[string]int, 10)
	fmt.Printf("m2的类型:%T\n", m2)
	fmt.Printf("m2是否为nil:%t\n", m2 == nil) // false
}

添加键值对

语法格式

go
变量名[键类型] = 值类型

示例

go
package main

import "fmt"

func main() {
	// 创建map
	m1 := map[string]string{
		"name":    "MagicGopher",
		"age":     "18",
		"address": "银河系地球",
	}
	// map可以通过len函数获取map的长度
	fmt.Printf("m1的长度:%d\n", len(m1))
	// map是无法通过cap函数获取map的容量的
	// fmt.Printf("m1的容量:%d\n", cap(m1))
	// map的值
	fmt.Printf("m1的值:%v\n", m1)
}
go
package main

import "fmt"

func main() {
	// 创建map
	m1 := make(map[string]string)
	m1["name"] = "MagicGopher"
	m1["age"] = "18"
	m1["address"] = "银河系地球"
	// map可以通过len函数获取map的长度
	fmt.Printf("m1的长度:%d\n", len(m1))
	// map是无法通过cap函数获取map的容量的
	// fmt.Printf("m1的容量:%d\n", cap(m1))
	// map的值
	fmt.Printf("m1的值:%v\n", m1)
}

通过键获取值

语法格式

go
变量名[键]

示例

go
package main

import "fmt"

func main() {
	// 创建map
	m1 := map[int]string{
		1: "java",
		2: "golang",
		3: "python",
		4: "c++",
		5: "rust",
	}
	// 通过键获取值
	fmt.Printf("m1[1] = %v\n", m1[3])
	// 获取不存在的键,返回值是数据类型的默认值
	fmt.Printf("m1[6] = %v\n", m1[6])
}

遍历map

可以通过 for range 遍历map,在遍历map时,键是只读的而值是可读写的。

示例

go
package main

import "fmt"

func main() {
	// 可以用 for range 获取 key-value 对,key 是只读的,value 是可读写的。
	// Go 语言中 map 的 key 是不能直接修改的。
	// 定义map
	m := map[string]int{"a": 1, "b": 2}
	fmt.Println("修改前的map:", m)
	// 遍历 map,修改 value
	for k, v := range m {
		fmt.Println("修改前:", k, v)
		m[k] = v * 2
		fmt.Println("修改后:", k, m[k])
	}
	fmt.Println("修改后的map:", m)
}

map中移除元素

可以使用delete()函数移除map中的元素。

语法格式

go
delete(map变量, 要删除的键)

示例

go
package main

import "fmt"

func main() {
	// 使用delete删除键值对
	m := map[string]int{
		"a": 1,
		"b": 2,
		"c": 3,
	}
	// for range遍历map
	for k, v := range m {
		println(k, v)
	}
	// 删除键值对
	delete(m, "a")
	fmt.Println("============")
	// 再遍历map
	for k, v := range m {
		println(k, v)
	}
	// 追加元素
	m["test"] = 100
	fmt.Println("============")
	// 再遍历map
	for k, v := range m {
		println(k, v)
	}
}

判断键的值是否存在

可以使用 map[key] 的方式来尝试访问map中的某个键,如果该键存在,就会返回对应的值,如果该键不存在,就会返回该值类型的零值【默认值】。

语法格式

go
键对应的值, 结果 := map变量名[键值]

示例

go
package main

import "fmt"

func main() {
	// 定义一个map
	myMap := map[int]string{
		1: "apple",
		2: "banana",
		3: "orange",
	}
	// 判断键的值是否存在
	value, ok := myMap[1]
	fmt.Printf("value:%v, ok:%v\n", value, ok)
	value, ok = myMap[4]
	fmt.Printf("value:%v, ok:%v\n", value, ok)
}
go
package main

import "fmt"

func main() {
	// 创建一个 map
	m := map[string]int{
		"苹果": 5,
		"香蕉": 3,
		"橙子": 7,
	}

	// 检查 "香蕉" 键是否存在
	value, ok := m["香蕉"]
	if ok {
		fmt.Printf("'香蕉' 的值是: %d\n", value)
	} else {
		fmt.Println("'香蕉' 键不存在于 map 中")
	}

	// 检查 "梨" 键是否存在
	value, ok = m[""]
	if ok {
		fmt.Printf("'梨' 的值是: %d\n", value)
	} else {
		fmt.Println("'梨' 键不存在于 map 中")
	}
}

使用map的注意事项

map使用时的注意事项

  • map是无序的,每次打印出来的map都会不一样,它不能通过index获取,而必须通过key获取。
  • map的长度是不固定的,也就是和slice一样,也是一种引用类型。
  • 内置的len函数同样适用于map,返回map拥有的key的数量。
  • map的key可以是所有可比较的类型,如布尔型、整数型、浮点型、复杂型、字符串型...也可以键。

根据 MIT 许可证发布