golang 之 Map 思考

1. 写在最前面

最近 review 代码的时候,遇到了很多 map[string]pointer 的写法,之前这种写法的时候,笔者总是以 C/C++ 的角度思考,这样写其实是为了节省内存,但其实不然,除了节省内存,还有其他的意义。

2. 值 vs 指针修改生效问题

先看一个例子,定义一个结构体,其存在两种方法:

  • 值类的方法
  • 指针类的方法
package main

import "fmt"

type Person struct {
	name string
	age  int
}

// 指针类的方法
func (p *Person) updateName(n string) {
	p.name = n
}

// 值类的方法
func (p Person) updateAge(a int) {
	p.age = a
}

func updateByValue() {
	p := Person{
		name: "xiyan",
		age:  28,
	}
	fmt.Printf("updateByValue before %v\n", p)
	p.updateAge(29)
	p.updateName("new-xiyan")
	fmt.Printf("updateByValue after %v\n", p)
}

func updateByPointer() {
	p := &Person{
		name: "xiyan",
		age:  28,
	}
	fmt.Printf("updateByPointer before %v\n", p)
	p.updateAge(29)
	p.updateName("new-xiyan")
	fmt.Printf("updateByPointer after %v\n", p)
}

func main() {
	updateByValue() // 值的修改方法不生效
	fmt.Println("=================================")
	updateByPointer() // 指针的修改方法生效
}

结论:只有定义为指针的方法的修改才能生效。

在这里插入图片描述

3. 值 vs 指针修改寻址问题

还是上述的例子,直接寻址 map 中定义的值和指针类型的结构体:

package main

type Person struct {
	name string
	age  int
}

func (p *Person) updateName(n string) {
	p.name = n
}

func (p Person) updateAge(a int) {
	p.age = a
}

func main() {
	m1 := map[string]*Person{
		"xiyan": {
			name: "xiyan",
			age:  28,
		},
	}
	// 指针类型的结构体能够直接寻址
	(m1["xiyan"]).name = "hehe"

	m2 := map[string]Person{
		"xiyan": {
			name: "xiyan",
			age:  28,
		},
	}
	// 值类型的结构体不能够直接寻址
	(m2["xiyan"]).name = "hehe"
	(m2["xiyan"]).age = 29

}

结论:值类型结构体上的寻址会报错。cannot assign to struct field xxx in map

在这里插入图片描述

4. Why 什么值类型无法寻址

m2 的 value 存储的是 Person 结构体的值,所有m2[“xiyan”] 不是一个常规的可寻址值:hashmaps 可以在运行时增长,然后它们的值在内存中移动,旧位置变得过时。那么映射实现的内部结构就会暴露出来。

m1 的 value 存储的是 Person 结构体的指针,其结构体占用的内存已经分配成功,且不会随着 hashmaps 的扩容而改变,所以 m1[“xiyan”] 是可寻址的值。

5. 碎碎念

哎,今天真的是各种撕,快疯了的一天:

  • 女孩子太容易自责和自我否定。这个世界有时候是有点问题的,你要学会明辨是非。而不是人云亦云。大家都说女孩子要听话,要主内,问问你自己的内心,你真的愿意这样做吗?如果不愿意,就学会说 NO,爱自己就是做自己喜欢的事情,只要不违反法律和道德,与世界为敌又如何?
  • ♡ 盐于律己,甜以待人

6. 参考资料

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值