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

相关推荐
码事漫谈3 小时前
C++死锁深度解析:从成因到预防与避免
后端
码事漫谈3 小时前
智能体颠覆教育行业:现状、应用与未来展望调研报告
后端
蓝-萧3 小时前
【玩转全栈】----Django基本配置和介绍
java·后端
priority_key3 小时前
排序算法:堆排序、快速排序、归并排序
java·后端·算法·排序算法·归并排序·堆排序·快速排序
韩立学长3 小时前
基于Springboot的旧时月历史论坛4099k6s9(程序、源码、数据库、调试部署方案及开发环境)系统界面展示及获取方式置于文档末尾,可供参考。
数据库·spring boot·后端
编程社区管理员3 小时前
React 发送短信验证码和验证码校验功能组件
前端·javascript·react.js
全马必破三3 小时前
React“组件即函数”
前端·javascript·react.js
三思而后行,慎承诺3 小时前
React 底层原理
前端·react.js·前端框架
座山雕~3 小时前
html 和css基础常用的标签和样式
前端·css·html
汤姆yu4 小时前
基于SpringBoot的动漫周边商场系统的设计与开发
java·spring boot·后端