当前位置: 首页 > 科技观察

为什么Go语言建议append添加新元素,并使用原来的slice变量接收返回值?

时间:2023-03-12 18:45:07 科技观察

1。介绍在Go语言中,slice类型是比较常用的,而且往slice追加新元素也很常见,所以Go语言提供了一个内置函数append,可以很方便的实现这个功能。Go语言的内置函数append虽然使用起来非常方便,但是如果使用不当,也会一不小心掉进一些“陷阱”。在这篇文章中,我们介绍了为什么Go语言推荐append来添加新元素,并使用原来的slice变量来接收返回值?2.append的“坑”先看一个示例代码:funcmain(){a:=make([]int,0,5)a=append(a,1)b:=append(a,2)c:=append(a,3)fmt.Printf("v=%v||p=%p\n",a,&a)fmt.Printf("v=%v||p=%p\n",b,&b)fmt.Printf("v=%v||p=%p\n",c,&c)}看上面的代码,我们定义了一个长度为0,容量为5的int类型的切片a。首先,我们使用Go语言内置函数append将元素1添加到切片a。然后,我们使用Go语言内置函数append将元素2添加到切片a。最后,我们使用Go语言内置函数append将元素3附加到切片a。但是我们在输出结果中发现b的输出结果不是[12],c的输出结果不是[123],b和c的实际输出结果是一样的,都是[13]。为什么?下面继续03部分的内容。3.append的原理Go语言内置函数append的第一个入参是slice类型的变量,slice本身是一个struct结构体,value传递参数时发生复制。Go语言slice源码如下:typeslicestruct{arrayunsafe.Pointerlenintcapint}因为Go语言内置函数append参数是传值的,所以append函数追加新元素时到切片,append会生成一个新的切片,并将原切片的值复制到新的切片中。在Part02的示例代码中,我们三次使用append参数向切片a追加新元素,接收返回值的变量不同。在第二个操作中,因为append生成了一个新的切片,所以将原切片a的值复制到新的切片中,并在原切片a[len(a)]的长度处追加新元素,并且变量b用来接收append返回值[12],所以变量b的值为[12]。第三个操作,同样append生成一个新切片,将原切片a的值复制到新切片中,并在原切片a[len(a)]的长度处追加新元素,并使用变量c接收append返回值是[13],所以变量c的值为[13]。但是,由于三个切片的底层数组相同,Go内置函数append会从原切片的长度开始追加新元素,所以第三个操作覆盖了第二个获取的变量b的最后一个元素手术。读到这里,相信聪明的读者已经明白为什么Part02示例代码的实际输出和预期的输出不一样了。4.总结在这篇文章中,我们介绍了Go语言中的一个“坑”,即使用内置函数append追加新元素。建议读者朋友使用原始切片变量接收返回值。参考资料:https://img.ydisp.cn/news/20220926/sxiglsues4hdata-id="ld70c578-kUa7wX13">https://img.ydisp.cn/news/20220926/0nc1bdmue1wdata-id="ld70c578-GouRLuFj">https://go.dev/blog/slices-introhttps://img.ydisp.cn/news/20220926/i2q3abyptmodata-id="ld70c578-fzqJ288r">https://img.ydisp.cn/news/20220926/dzlhy0w4u3tdata-id="ld70c578-1ikv2iLZ">https://img.ydisp.cn/news/20220926/fm0royaechwdata-id="ld70c578-IfmR3UGo">https://img.ydisp.cn/news/20220926/slhixzu1edfdata-id="ld70c578-lk7iHCEi">https://img.ydisp.cn/news/20220926/4rmcxp15wd5