Golang切片索引返回值还是引用?结构体切片修改疑惑求助
Go切片索引修改元素的原理解析
先看你的代码定义:
type bag struct { item string } itemBag := []bag{ {item: "item1"}, {item: "item2"}, {item: "item3"} }
下面分三种情况拆解原因:
item1 := itemBag[0]修改不生效bag是值类型,当你通过itemBag[0]获取元素时,Go会返回该元素的副本。你把副本赋值给item1后,修改item1.item只是修改了这个副本的字段,和原切片里的元素完全是两块独立的内存,所以原切片不会有变化。item1 := &itemBag[0]修改生效
这里你取的是itemBag[0]的内存地址,item1是指向原切片第一个元素的指针。修改item1.item本质是直接操作原元素所在的内存空间,所以原切片的元素会跟着改变。直接
itemBag[0].item = "not item1"生效
这是Go的语法糖优化。虽然itemBag[0]返回的是值副本,但Go允许直接对这个副本的字段进行赋值,底层会自动转换为对原元素内存地址的字段修改,等价于(&itemBag[0]).item = "not item1",所以能直接修改原切片的元素。
总结一下:值类型的切片元素,直接索引赋值得到的是副本,修改副本不影响原元素;但直接对索引返回值的字段赋值,Go会帮你自动处理成修改原元素;而取索引元素的指针,就是直接操作原元素内存。
内容的提问来源于stack exchange,提问作者mingjun
相关产品推荐
相关产品推荐

