Go语言中copy()内置函数的作用是什么?赋值已支持浅拷贝
Go中copy()内置函数的浅拷贝特性与赋值操作的区别
一、copy()执行的是浅拷贝
没错,copy()内置函数实现的是浅拷贝:
- 如果切片元素是值类型(如int、string、struct等),
copy()会直接复制元素的值到目标切片的底层数组中; - 如果切片元素是引用类型(如指针、map、切片等),
copy()只会复制元素的引用,两个切片的元素会指向同一个底层引用对象,修改其中一个会影响另一个。
二、赋值操作和copy()的核心区别
你例子里的误解源于对切片赋值本质的认知:
- 切片赋值(
dst = src)只是让目标切片变量指向源切片的同一个底层数组,相当于两个切片共享同一份数据,并没有任何复制操作; - copy()函数是将源切片的元素值复制到目标切片的底层数组中,两个切片可以拥有独立的底层数组,彼此的数据互不干扰(元素是值类型时)。
对比示例1:赋值操作的共享特性
package main import "fmt" func main() { src := []int{1, 2, 3} dst := src // 赋值操作,共享底层数组 src[0] = 100 // 修改源切片的元素 fmt.Println(dst) // 输出 [100 2 3],目标切片也受影响 }
对比示例2:copy()的独立复制特性
package main import "fmt" func main() { src := []int{1, 2, 3} dst := make([]int, len(src)) // 创建独立的底层数组 copy(dst, src) // 复制元素值 src[0] = 100 // 修改源切片的元素 fmt.Println(dst) // 输出 [1 2 3],目标切片不受影响 }
三、copy()的实际作用
当你需要以下场景时,copy()是不可替代的:
- 想要创建一个与原切片数据独立的新切片,修改新切片不会影响原切片;
- 将源切片的元素复制到目标切片的指定位置(比如目标切片长度大于源切片,只覆盖前N个元素);
- 处理切片扩容或需要保留原数据的场景,比如在不修改原切片的前提下,基于原数据生成可修改的副本。
修正你提供的示例(展现copy()的真实行为)
你原示例中dst = src已经让两个切片共享底层数组,后续copy()操作是在同一个数组内复制,所以地址不变。如果跳过赋值直接执行copy(),就能看到底层数组的独立性:
package main import "fmt" func main() { var src = []int{1, 2, 3, 4, 5} var dst []int = make([]int, 10) fmt.Println(&src[0]) // 示例地址:0xc00001c210 fmt.Println(&dst[0]) // 示例地址:0xc00001c240(与src地址不同) copy(dst, src) fmt.Println(&dst[0]) // 仍为0xc00001c240,说明值复制到了dst的独立数组中 fmt.Println(dst[:5]) // 输出 [1 2 3 4 5] }
内容的提问来源于stack exchange,提问作者overexchange
相关产品推荐
相关产品推荐

