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一种方法,在代码库中看到其它拷贝元素方法时不要惊讶。

相关推荐
爱勇宝11 小时前
我做了一个排版器,也踩了一遍富文本复制的坑
前端·后端·微信
布朗克16811 小时前
Go 入门到精通-33-unsafe 与 CGO
开发语言·后端·golang·unsafe·cgo
铁皮饭盒11 小时前
面试官:如何用 Bun + JS 实现安全的文件 MCP 工具集
前端·javascript·后端
小Ti客栈12 小时前
Spring Boot 整合 Swagger2 和 Knife4j实现接口文档与可视化调试
java·spring boot·后端
明月_清风12 小时前
💰 DeFi 入门完全指南:从 Uniswap 到 Aave,一文读懂去中心化金融
后端·web3
Conan在掘金12 小时前
鸿蒙报错速查:struct 里嵌套 @Component struct 就炸,Unexpected keyword 编译报错,根因 + 真解法
后端
探索前端12 小时前
Cesium图层加载及影像服务添加
前端·cesium
妙码生花12 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(三十六):多驱动上传接口
后端·go·ai编程
明月_清风12 小时前
🎨 NFT 全景解析:从 JPEG 到数字所有权革命
后端·web3
阿懂在掘金12 小时前
Vue 弹窗新范式——代码减少、复用翻倍与 AI 时代的前端基建
前端·设计模式·前端框架