Go语言中常见100问题-#24 切片拷贝最佳实践

切片拷贝

内置的 copy 函数实现了将源切片中的数据拷贝到目标切片中的功能,尽管这是一个常用的内置函数,但是还是有不少开发者使用有误。下面会通过具体的例子说明 copy 的错误使用。

案例引入

如下代码中期望通过 copy 函数将源切片 src 中的数据拷贝到目标切片 dst中,猜猜程序打印的内容是什么?

golang 复制代码
src := []int{0, 1, 2}
var dst []int
copy(dst, src)
fmt.Println(dst)

执行上述程序,输出内容是\[\], 并不是我们预期的0 1 2, 为啥呢?

原因分析

需要对copy有深入的理解。copy函数将源切片中的数据拷贝到目标切片时,拷贝的元素个数为下面两个长度中较小的一个。

  • 源切片的长度

  • 目标切片的长度

在前面的代码中,源切片src的长度为3,但是目标切片dst的长度为0,因此,调用copy函数拷贝的元素个数为0,所以打印输出为空切片。

常规解决方法

如果我们想进行完整的拷贝,目标切片的长度必须不小于源切片的长度。像下面这样,将目标切片的长度设置为与源切片一样长,这时打印输出内容为0 1 2.

golang 复制代码
src := []int{0, 1, 2}
dst := make([]int, len(src))
copy(dst, src)
fmt.Println(dst)

NOTE:另一个常犯的错误是颠倒了调用copy函数参数顺序。记住第一个参数表示将元素拷贝到的目标位置,第二参数是源数据的位置。

特殊处理方法

拷贝元素并不是只有调用copy函数一种方式,在其他实现方法中最广泛熟知的是下面这种通过append函数的方法。将源切片append到一个nil切片中,这时将创建一个长度为3,容量为3的目标切片。相比前一种方法,这种方法优势是代码简短,只需要一行代码。但是使用copy更地道,更容易理解。

golang 复制代码
src := []int{0, 1, 2}
dst := append([]int(nil), src...)

总结

将一个切片中的元素拷贝到另一个切片是一种非常频繁的操作,当我们使用copy函数时,需要记得拷贝的元素个数是源切片和目标切片中长度较短的。此外,需要知道拷贝元素并不是只有copy一种方法,在代码库中看到其它拷贝元素方法时不要惊讶。

相关推荐
Jmyd01236 小时前
Web端3D营销展厅技术实现路径:从素材上云到线索回流的数据链路
前端·3d·性能优化·三维数字化
砚凝霜6 小时前
【软考信息安全】第二十二章 Web服务器安全分析与增强——Apache与IIS
服务器·前端·安全
大鸡腿同学7 小时前
手心向上,手心向下
后端
CCblandy8 小时前
令牌桶在 0.9 倍负载超发 19%、固定窗口边界放行 20 个:四种限流算法同构实测
后端·python·算法·性能优化·架构
u0111026758 小时前
JPG、PNG、WebP 怎么选?按透明度、体积和使用场景做判断
前端·javascript·vue.js·图像处理·ai作画
jerrywus9 小时前
让 AI 写完代码后交一份报告:我改造了 answer-me-with-html
前端·claude·cursor
派小心.9 小时前
小程序分享链路中来源参数的传递校验
大数据·前端·数据库·人工智能·小程序·数据分析
凤山老林10 小时前
Spring Boot 集成 Sa-Token 实现高可用权限认证:登录鉴权、动态路由权限与接口防重放实战
spring boot·后端·sa-token·bootstrap
hhb_61810 小时前
一键生成数据看板,ECharts实战演示
前端·javascript·echarts
Java后端的Ai之路10 小时前
08_React组件API
前端·react.js·前端框架