返回文章列表

【Go】映射

2024年8月16日
Go

映射的内部实现和基础功能

映射是一种数据结构,用于存储一些列无序的键值对。

内部实现

映射是一个集合。可以使用类似处理数组和切片的方式迭代映射中的元素。但映射是无序集合,意味着即使使用同样的顺序保存键值对,每次迭代映射的时候顺序也可能不一样。无序的原因是映射的实现使用了散列表。

创建和初始化

Go语言中有很多方法可以创建并初始化映射,可以使用内置的make函数,如:

// 创建一个映射,键的类型是string,值的类型是int
dict := make(map[string]int)
// 创建一个映射,键和值都是string,并初始化
newDict := map[string]string{"red": "#da1337", "orange": "#e95a22"} 

创建映射是,更常用的方法是使用映射字面量。映射的初始长度会根据初始化时键值对的数量来确定。映射的键可以是任何值,这个值的类型可以是内置的类型,也可以是结构类型,只要这个值可以使用 == 运算符做比较。切片、函数以及包含切片的结构类型这些类型由于具有引用语义,不能作为映射的键。如:

// 创建一个映射,使用字符串切片作为映射的键
dict := map[[]string]int{} //invalid map key type []string
// 可以使用切片作为映射的值,声明一个存储字符串切片的映射
newDict := map[int][]string{}

使用映射

键值对赋值给映射,是通过指定适当类型的键并给这个键赋一个值来完成,如:

// 创建一个空映射
colors := map[string]string{}
colors["red"] = "#da1337"

可以通过声明一个未初始化的映射来创建一个值为nil的映射(称为nil映射)。nil映射不能用于存储键值对,否则,会产生一个运行时错误,如:

// 通过声明映射创建一个nil映射
var colors map[string]string
colors["r"] = "red" // assignment to entry in nil map

测试映射是否存在某个键是映射的一个重要操作。从映射中取值有两个选择。 one:可以同时获得值,以及一个表示这个键是否存在的标志,如:

value, exists := colors["r"]
if exits {
    fmt.Println(value)
}

two: 只返回键对应的值,然后通过判断这个值是不是零值来确定键是否存在,如:

value := colors["r"]
if value != "" {
    fmt.Println(value)
}

迭代映射,和迭代数组或切片一样,使用关键字range,如:

colors := map[string]string{
    "r": "red",
    "y": "yellow",
    "b": "blue",
}
for key, value := range colors {
    fmt.Printf("key: %s value: %s\n", key, value)
}
// key: r value: red
// key: y value: yellow
// key: b value: blue

如果想把一个键值对从映射里删除,就使用内置的delete函数,如:

delete(colors, "r")
for key, value := range colors {
    fmt.Printf("key: %s value: %s\n", key, value)
}
// key: y value: yellow
// key: b value: blue

在函数间传递映射

在函数间传递映射不是复制该映射。当在函数中对这个映射做了修改时,所有对这个映射的引用都会改变。如:

package main

import "fmt"

func main (){
	colors := map[string]string{
		"r": "red",
		"y": "yellow",
		"b": "blue",
		"w": "white",
		"o": "orange",
	}
	for key, value := range colors {
		fmt.Printf("key: %s value: %s\n", key, value)
    }
    fmt.Printf("\n")
	removeColors(colors, "r")
	for key, value := range colors {
		fmt.Printf("key: %s value: %s\n", key, value)
	}
}

func removeColors(new map[string]string, key string) {
	delete(new, key)
}
// key: o value: orange
// key: r value: red
// key: y value: yellow
// key: b value: blue
// key: w value: white

// key: y value: yellow
// key: b value: blue
// key: w value: white
// key: o value: orange