golang 之 map 新玩法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/phantom_111/article/details/82261533

笔者接触 golang 也有两年的时间了,最常用的以string为key map 类型无非就是 map[string] 基础类型(int、string、float等)、map[string]interface{}、map[string]struct 这几类,说来惭愧,以前抽象数据结构,在用多维 map 的时候都是将第二维的 map 用一个单独的 struct 包装之后再使用。

以前都是这么用的:

//key 代表姓名
//value 代表年龄
type person struct {
    ageInfo map[string]int
}

//key 代表班级
//value 代表该班级的学生
class := map[string][]person

了解新玩法了之后,感觉打开了一扇大门:

//第一维 map 的 key 表示班级
//第二维 map 代表学生,key 为姓名, value 为年龄
class := map[string]map[string]int

多维 map 用法

按照上面的例子,抽象结构之后,很可能会这么写代码

package main

import (
    "fmt"
)

func main() {
    cm := make(map[string]map[string]int,0)
    cm["三年一班"]["王小明"] = 10
    fmt.Println("info", cm)
}

你以为这么写真的对吗?运行一下看看结果:

panic: assignment to entry in nil map

goroutine 1 [running]:
main.main()
    /tmp/sandbox913968657/main.go:9 +0xa0

果然不能这么轻易就成功,报错提示正在给一个 nil map 赋值,可是 cm 这个不是已经初始化了吗?别忘了,编译器可不知道 cm 这个 map 是二维的 map ,所以在使用的时候就需要你手动的赋值了

正确给二维 map 赋值的姿势

笨笨的姿势

最容易想到的,往往就是那个最繁琐的姿势,所以以后写代码的时候要多想想

package main

import (
    "fmt"
)

func main() {
    cm := make(map[string]map[string]int,0)
    pm := make(map[string]int,0)
    pm["王小明"] = 10
    cm["三年一班"] = pm
    fmt.Println("info", cm)
}

运行结果:

info map[三年一班:map[王小明:10]]

更优美的姿势

作为一名追求完美软件开发人员,下面这种应该是你最合适的选择:

package main

import (
    "fmt"
)

func main() {
    cm := make(map[string]map[string]int,0)
    cm["三年一班"] = map[string]int{
        "王小明": 10,
    }
    fmt.Println("info", cm)
}

运行结果:

info map[三年一班:map[王小明:10]]

很多时候,写代码之前多想想就会有很多的新收获,你以为文章到这里就结束了?no,下面我要分享我的新收获了。

多问问为什么?

golang 中的引用类型有 map、channel、slice(int、string、float等其它的类型为值类型)引用类型就是在访问过程中修改存储的值,这种修改在后续的操作中是可见的。那么问题来了:

  • map 的 value 用什么类型比较合适?
  • 二维 map 见过了之后,考虑下 map 的 value 如果是 slice 类型这种应该怎么赋值?

map 的 value 用值还是引用

其实正确答案我也不知道,但个人认为这个跟你自己的要存储的数据有关,如果修改需要对后续的操作可见,就用引用类型;如果对占用的内存有限制,也用引用类型

注意: 暂时只想到这两个,后续持续补充好了��

map 的 value 是 slice 类型

秉承举一反三的思维,我猜你肯定也是这么写的:

package main

import (
    "fmt"
)

func main() {
    cm := make(map[string][]string,0)
    cm["三年一班"] = []string{"王小明","李晓红"}
    fmt.Println("first print info", cm)
    //增加一个元素试试
    cm["三年一班"] = append(cm["三年一班"],"夏天")
    fmt.Println("second print info", cm)
}

打印结果:

first print info map[三年一班:[王小明 李晓红]]
second print info map[三年一班:[王小明 李晓红 夏天]]

猜你喜欢

转载自blog.csdn.net/phantom_111/article/details/82261533
今日推荐