您的位置 首页 golang

Golang 复合数据类型:映射


映射(map)

映射是一种数据结构,用于存储一系列无序的键值对,映射基于键来存值,能够快速检索数据。键就像索引一样,指向与该键关联的值。

映射的实现

Go语言中 map 的底层是哈希(hash)表实现的,它的源码在 $GOROOT/src/pkg/runtime/hashmap.go/ 可以查看它的实现细节。Go语言的 map 是一个数组列表,不是像 C++ 一样使用红黑树,与传统的 hashmap 一样,Go语言的 map 由一个个 bucket 组成。在这个数组列表中的每一个元素都被称为 bucket 的结构体,每个 bucket 可以保存为 8 个键值对,所有元素将被 hash 算法填入到数组的 bucket 中;当 bucket 填满后,会使用一个 overflow 指针来扩展一个 bucket ,从而形成链表,以此解决 hash 冲突的问题。

映射的创建和初始化

  • 使用make函数创建映射
  • 使用映射字面量(常用)
func main(){    //使用make函数创建映射    a1 := make(map[string]int)    fmt.Println(a1)  //打印零值    //使用映射字面量初始化    a1 = map[string]int{"Cat":1,"Dog":2,"Bee":3}    fmt.Println(a1)}/*map[]map[Bee:3 Cat:1 Dog:2]*/

使用映射字面量初始化是常用的方法,映射的初始长度会根据初始化时指定的键值对的数量来确定。映射的键可以是任何类型的值,内置类型或者结构类型都可以,不过需要确定这个值可以用 == 比较运算符做比较。需要注意的是,切片函数以及包含切片结构类型由于具有引用语义,所以这些数据类型都不能用作映射的键,编译器会报错:

//创建一个映射,使用字符串切片作为映射的键func main(){    dict := map[[]string]int{}    fmt.Println(dict)}/*command-line-argumentsinvalid map key type []string*/

但是可以使用切片作为映射的值

//创建一个映射,使用字符串切片作为映射的值func main(){    dict := map[int][]string{}    fmt.Println(dict)}/*map[]*/

映射的使用

  • 元素赋值

    通过指定适当类型的键并给这个键赋值就完成了映射的键值对赋值。

    func main(){    //使用空字面量创建初始化后的空映射    dict := map[string]int{}    fmt.Println(dict)    //映射赋值    dict["Star"] = 1    fmt.Println(dict)    //使用make函数创建初始化后的空映射    dict1 := make(map[string]int)    fmt.Println(dict1)    //映射赋值    dict1["Moon"] = 2    fmt.Println(dict1)}/*map[]map[Star:1]map[]map[Moon:2]*/

    声明一个未初始化的映射可以产生值为 nil 的映射。nil 映射不能用于存储键值对,否则编译器会抛出panic异常

    func main(){    //创建一个未初始化的空映射,值为 nil     var dict map[string]int    //nil 映射赋值    dict["Star"] = 1    fmt.Println(dict)}/*panic: assignment to entry in nil map*/

    映射的查找和遍历

    映射取值有两种方式:

    • 先获取对应键的值,再判断是否存在,若存在则打印值,若不存在则什么也不做
    • 先取取对应键的值,再判断值是否为零值 (如果非空,说明存在;如果为空,说明不存在)
    func main() {    //使用字面量创建初始化后的映射    dict := map[string]int{"Cat": 1, "Dog": 2, "Bee": 3}    //方法一:映射取值,获得键对应的值    value, exists := dict["Dog"]    if exists {        fmt.Println(value)    }    //方法二:先取对应键的值,再判断值是否为零值 如果非空,说明存在;如果为空,说明不存在    value = dict["Cat"]         if value != 0 {        fmt.Println(value)    }}/*21*/

在Go语言里,通过键来索引映射时,即便这个键不存在,也会返回该值对应类型的零值。

  • 映射遍历

    func main() {    //使用字面量创建初始化后的映射    dict := map[string]int{"Cat": 1, "Dog": 2, "Bee": 3}    //映射遍历    for i,v := range dict {        fmt.Println(i,v)    }}/*Cat 1Dog 2Bee 3*/
  • 元素删除

    Go语言里提供了内置函数 delete() 用于删除容器内的元素。

    func main() {    //使用字面量创建初始化后的映射    dict := map[string]int{"Cat": 1, "Dog": 2, "Bee": 3}    fmt.Println(dict)    //删除元素    delete(dict,"Cat")    fmt.Println(dict)}/*map[Bee:3 Cat:1 Dog:2]map[Bee:3 Dog:2]*/

将映射传递给函数

在函数间传递映射并不会制造出该映射的一个副本

func main() {// 创建一个映射,存储颜色以及颜色对应的十六进制代码myColors := map[string]string{"AliceBlue":"#f0f8ff","Coral":"#ff7F50","DarkGray":"#a9a9a9","ForestGreen": "#228b22",}// 显示映射里的所有颜色for key, value := range myColors {fmt.Printf("Key: %s  Value: %s\n", key, value)}fmt.Println()// 调用函数来移除指定的键removeColor(myColors, "Coral")// 显示映射里的所有颜色for key, value := range myColors {fmt.Printf("Key: %s Value: %s\n", key, value)}}// removeColor 将指定映射里的键删除func removeColor(colors map[string]string, key string) {delete(colors, key)}/*Key: AliceBlue  Value: #f0f8ffKey: Coral  Value: #ff7F50Key: DarkGray  Value: #a9a9a9Key: ForestGreen  Value: #228b22Key: AliceBlue Value: #f0f8ffKey: DarkGray Value: #a9a9a9Key: ForestGreen Value: #228b22*/

文章来源:智云一二三科技

文章标题:Golang 复合数据类型:映射

文章地址:https://www.zhihuclub.com/3453.shtml

关于作者: 智云科技

热门文章

网站地图