你以为切片复制就是等号一键搞定?太多Go新手栽在这个坑里了!
1. 切片复制:Go程序员的第一课
作为一名Gopher(Go程序员),slice(切片)绝对是我们日常编码中最常用的数据结构之一。想象一下,你手里有一个装满数据的切片,现在需要创建一个它的独立副本,修改副本时不会影响原数据——这就是切片复制的典型场景。
在Go语言中,复制切片有多种方式,但最常用且官方推荐的就是内置的copy()函数。不过,很多新手会想当然地直接用等号(=)来复制,结果踩了不少坑。
事实上,切片本质上是一个结构体类型,包含三个字段:指向底层数组的指针、切片的长度和容量。当你使用s1 := s2这样的赋值操作时,你只是在复制这个结构体,而不是底层数组!这就意味着,两个切片会共享同一个底层数组,对一个切片的修改会影响另一个。
来看一个血淋淋的例子:
func main() {
s1 := []int{1, 2, 3, 4, 5}
s2 := s1 // 浅拷贝,共享底层数组
s2[0] = 999 // 修改s2
fmt.Println("s1:", s1) // 输出啥?[999 2 3 4 5]
fmt.Println("s2:", s2) // 输出啥?[999 2 3 4 5]
}
看到没!修改s2的同时s1也被修改了,这就像你买了一盒巧克力,分给别人一半,结果发现自己盒子里的巧克力也少了一半——多么痛的领悟!
2. copy()函数:你的切片复制救星
2.1 copy()函数到底是什么?
copy()是Go语言提供的内置函数,用于将元素从一个切片复制到另一个切片。它的函数签名很简单:
func copy(dst, src []Type) int
dst:目标切片,数据将被复制到这里src:源切片,数据从这里复制- 返回值:实际复制的元素个数
2.2 第一次使用copy():可能遇到的坑
来看新手经常写错的代码:
func main() {
src := []int{0, 1, 2}
var dst []int // 声明但未初始化,此时dst为nil
copy(dst, src) // 执行复制
fmt.Println(dst) // 输出:[],空切片!
}
为什么是空的?因为copy()函数的行为是:复制两个切片中长度较小的那个长度的元素。在这个例子中,dst的长度是0,src的长度是3,所以只会复制0个元素。
用公式表示就是:
拷贝到变量dst中的元素个数 = min(len(dst), len(src)) <

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



