go结构体切片如何赋新值不影响原值,建一个新的结构体切片副本

问题描述:
在开发xx需求时,要将一结构体切片完整的复制一份,然后修改其中某几个变量值,修改完后发现原结构体切片也被修改了。

package main
type Label struct {
	Name  string `json:"labelName"`
	Value string `json:"labelValue"`
}
func main(){
	a := []Label{
		{"aa", "aa-value"},
		{"bb", "bb-value"},
	}
	b := a
	b[0].Name = "cc"
	fmt.Println(a)
	fmt.Println(b)
}
// 打印如下
// 修改 b[0]后影响到了 a
[{cc aa-value} {bb bb-value}]
[{cc aa-value} {bb bb-value}]

问题原因:
go语言中切片的底层数据结构由三部分组成,分别是指向底层数组的指针、长度和容量。其中,指向底层数组的指针用于定位切片的起始位置,长度表示切片中实际存储的元素个数,容量表示切片可以容纳的最大元素个数,如下所示:

type slice struct {
    array unsafe.Pointer
    len   int
    cap   int
}

所以使用普通的赋值方式,slice struct中的 array 只是复制了一下指针给新的变量,新指针指向的地址仍旧跟原指针一样,所以修改新数据能影响到原数据。

问题修改:

    1. 使用 append 复制新副本
package main
type Label struct {
	Name  string `json:"labelName"`
	Value string `json:"labelValue"`
}
func main(){
	a := []Label{
		{"aa", "aa-value"},
		{"bb", "bb-value"},
	}
	// 等价于 append([]Label{}, a...)
	// []Label(nil) 表示新建一个长度为0的空切片 
	// 赋值整段代码等价于 d := make([]Label, 0);d = append(d, a...)
	c := append([]Label(nil), a...)
	c[0].Name = "cc"
	fmt.Println(a)
	fmt.Println(c)
}
// 打印如下
[{aa aa-value} {bb bb-value}]
[{cc aa-value} {bb bb-value}]
    1. 使用 copy 复制新副本
d := make([]Label, len(a))
copy(d, a)
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值