Go map 的值不可寻址,那如何修改值的属性?详解

要回答本题,需要你知道什么是不可寻址。

不急,请先看一下如下这段代码,你知道它有什么问题吗?

package main

type Person struct {
    Age int
}

func (p *Person) GrowUp() {
    p.Age++
}

func main() {
    m := map[string]Person{
        "iswbm": Person{Age: 20},
    }
    m["iswbm"].Age = 23
    m["iswbm"].GrowUp()
}

没错,这段代码是错误的,当你编译时,会直接报错呢?

原因在于这两行

    m["iswbm"].Age = 23
    m["iswbm"].GrowUp()

我们知道 map 的值是不可寻址的,当你使用 m["zhangsan"] 取得值时,其实返回的是其值的拷贝,虽然与原数据值相同,但是在内存中并不是同一个数据。

也正是这样,当 map 的值是一个普通对象(非指针),是无法直接对其修改的。

针对这种错误,解决方法有两种:

第一种:新建变量,修改后再覆盖

func main() {
    m := map[string]Person{
        "iswbm": Person{Age: 20},
    }
    p := m["iswbm"]
    p.Age = 23
    p.GrowUp()
    m["iswbm"] = p
}

第二种:使用指针的方式

func main() {
    m := map[string]*Person{
        "iswbm": &Person{Age: 20},
    }
    m["iswbm"].Age = 23
    m["iswbm"].GrowUp()
}

教程来源于Github,感谢iswbm大佬的无私奉献,致敬!

技术教程推荐

技术领导力实战笔记 -〔TGO鲲鹏会〕

分布式技术原理与算法解析 -〔聂鹏程〕

深入浅出云计算 -〔何恺铎〕

图解 Google V8 -〔李兵〕

Serverless入门课 -〔蒲松洋(秦粤)〕

分布式数据库30讲 -〔王磊〕

高楼的性能工程实战课 -〔高楼〕

技术领导力实战笔记 2022 -〔TGO 鲲鹏会〕

程序员职业规划手册 -〔雪梅〕