map
map
大体上来说,Go 中的映射是一个哈希表,是键值对的集合。 映射中所有的键都必须具有相同的类型,它们的值也是如此。 不过,可对键和值使用不同的类型。 例如,键可以是数字,值可以是字符串。 若要访问映射中的特定项,可引用该项的键。
1 声明和初始化映射
map[key]val
studentsAge := map[string]int{
"john": 32,
"bob": 31,
}
fmt.Println(studentsAge)
如果不想使用项来初始化映射,可使用内置函数 make() 在上一部分创建映射。 可使用以下代码创建空映射:
studentsAge := make(map[string]int) 映射是动态的。 创建项后,可添加、访问或删除这些项。 让我们来了解这些操作。
2 添加项
要添加项,无需像对切片一样使用内置函数。 映射更加简单。 你只需定义键和值即可。 如果没有键值对,则该项会添加到映射中。
若要避免在将项添加到映射时出现问题,请确保使用 make 函数(如我们在上述代码片段中所示)创建一个空映射(而不是 nil 映射) 此规则仅适用于添加项的情况。 如果在 nil 映射中运行查找、删除或循环操作,Go 不会执行 panic
var studentsAge map[string]int // this is nil map, this will panic: assignment to entry in nil map
studentsAge := make(map[string]int) // this is empty map, this is ok
studentsAge["john"] = 32
studentsAge["bob"] = 31
fmt.Println(studentsAge)
访问项 若要访问映射中的项,可使用常用的下标表示法 m[key],就像操作数组或切片一样。
studentsAge := make(map[string]int)
studentsAge["john"] = 32
studentsAge["bob"] = 31
fmt.Println("Bob's age is", studentsAge["bob"])
在映射中使用下标表示法时,即使映射中没有键,你也总会获得响应。 当你访问不存在的项时,Go 不会执行 panic。 此时,你会获得默认值。 可使用以下代码来确认该行为:
fmt.Println("Christy's age is", studentsAge["christy"])
Christy's age is 0
在很多情况下,访问映射中没有的项时 Go 不会返回错误,这是正常的。 但有时需要知道某个项是否存在。 在 Go 中,映射的下标表示法可生成两个值。 第一个是项的值。 第二个是指示键是否存在的布尔型标志。
要解决上一代码片段遇到的问题,可使用以下代码:
studentsAge := make(map[string]int)
age, exist := studentsAge["christy"]
if exist {
fmt.Println("Christy's age is", age)
} else {
fmt.Println("Christy's age couldn't be found")
}
3 删除项
若要从映射中删除项,请使用内置函数 delete()。 下例演示了如何从映射中删除项:
studentsAge := make(map[string]int)
delete(studentsAge, "john")
如果你尝试删除不存在的项,Go 不会执行 panic
studentsAge := make(map[string]int)
studentsAge["john"] = 32
studentsAge["bob"] = 31
delete(studentsAge, "christy")
映射中的循环 最后,让我们看看如何在映射中进行循环来以编程方式访问其所有的项。 为此,可使用基于范围的循环
studentsAge := make(map[string]int)
studentsAge["john"] = 32
studentsAge["bob"] = 31
for name, age := range studentsAge {
fmt.Printf("%s\t%d\n", name, age)
}
在本例中,我们将键保存在 name 变量中,将值保存在 age 变量中。 因此,range 会首先生成项的键,然后再生成该项的值。 可使用 _ 变量忽略其中任何一个
for _, age := range studentsAge {
fmt.Printf("Ages %d\n", age)
}