Linux教程网

Go语言内置函数copy复制切片

今天要聊的是 Go 语言内置的 copy() 函数,它的主要作用是把源切片的元素拷贝至目标切片中。

起初只看函数的名称,本以为是一个通用的函数,可以拷贝常见的基本数据类型。实际上 copy() 函数只能用于切片的拷贝,有点小失望了。

为什么会写这篇文章呢?今天在写 bug 时,要实现切片的拷贝,便查看官方文档发现 Go 本身就提供了拷贝函数。用法看似很简单,于是乎就用了起来,中间遇到了不少问题,跟自己臆想的不太一样,所以特来总结一下,希望看到文章的你少走一些弯路。

我们从一些实验代码来边看边聊

1
2
3
4
5
6
var s1 []string
s2 := []string{"1", "2", "3"}
// copy 函数很简单,第一个参数是目的切片,第二个参数是源切片
// s1是目的切片,s2是源切片,所以是要将s2拷贝s1
copy(s1, s2)
fmt.Println(s1) // 结果:[]

执行拷贝 copy() 函数后,s1 仍然为 [] 空切片。这是因为,切片 dst 需要先初始化长度,不是只定义类型就能将 s2 完全复制到 s1 中。

1
2
3
4
s1 := make([]string, 3)
s2 := []string{"1", "2", "3", "4", "5"}
copy(s1, s2)
fmt.Println(s1) // 结果:[1 2 3]

上边代码中,切片 s1 长度为 3,而源切片 s2 长度为 5,结果只拷贝到 s1 中 3 个元素。所以,如果目的切片长度小于源切片长度,copy() 只会拷贝部分元素。

1
2
3
4
5
s2 := []string{"1", "2", "3", "4", "5"}
s1 := make([]string, len(s2))
ret := copy(s1, s2)
fmt.Printf("len = %d s1 = %+v\n", ret, s1)
// 结果:len = 5 s1 = [1 2 3 4 5]

如果希望将 s2 完全拷贝到 s1 中,上述代码才是正确的拷贝姿势,copy() 函数会返回成功拷贝的元素的个数。

两个切片的拷贝,其实通过循环复制切片元素也很简单,所以总感觉 copy 函数有些蹩脚,但使用起来总比自己实现要方便多了。


专题:

本文发表于 2023-03-07,最后修改于 2023-09-17。

本站永久域名「 golinuxblog.com 」,也可搜索「 Linux教程网 」找到我。


上一篇 « 使用vscode搭建Go开发环境 下一篇 » Go语言生成随机数

推荐阅读

Big Image