Go语言循环中为结构体切片内元素的嵌入结构体赋值失效问题
问题根因
Go语言中使用for _, val := range slice遍历值类型切片时,迭代返回的val是切片元素的值拷贝,属于独立于原切片元素的临时变量。你代码中对x.A的赋值仅作用于这个临时拷贝,完全不会修改原切片z里的元素,该问题和是否使用嵌入结构体没有关联,属于range迭代的通用特性。
解决方案
有三种常用的修复方式,推荐优先使用第一种:
- 方式1:通过下标直接操作原切片元素
遍历的时候只拿索引,直接修改对应下标的元素,避免临时拷贝:for i := range z { z[i].A = c } - 方式2:将切片改为存储结构体指针
切片声明改为指针类型,此时range返回的指针拷贝仍指向原内存地址,修改会直接作用于原元素:// 声明切片为指针类型 var z []*B // append时传入指针 z = append(z, &B{b:"Test"}) z = append(z, &B{b:"Test"}) // 原有遍历逻辑可以保持不变 for _, x := range z { x.A = c } - 方式3:修改临时变量后回写到原切片
拿到修改后的临时变量,重新赋值给对应下标的位置,这种方式会多一次结构体拷贝开销,仅适合小结构体场景:for i, x := range z { x.A = c z[i] = x }
内容的提问来源于stack exchange,提问作者Elbo Shindi Pangestu
相关产品推荐
相关产品推荐

