copy(dst, src)要求dst已初始化且len>0,否则复制0个元素;它是浅拷贝,仅按字节搬运,不处理引用类型深层复制,性能接近memmove但无逻辑隔离。

copy(dst, src) 必须确保 dst 已初始化且 len > 0
直接对 nil 切片调用 copy 不会 panic,但复制元素数恒为 0,结果仍是空切片。这不是 bug,而是设计:它只按 len(dst) 和 len(src) 的较小值搬运,不负责分配内存。
-
dst必须是已 make 初始化的切片,例如make([]int, len(src))或make([]int, 0, len(src)) - 若只关心容量(如后续 append),可用
dst := make([]int, 0, len(src)),但此时len(dst) == 0,copy(dst, src)仍复制 0 个元素 - 常见错误:
var dst []string后直接copy(dst, src)→ 输出空切片,且无任何警告
copy 复制的是值,不是底层数据结构的递归克隆
copy 是浅拷贝,对 []*int、[]struct{ Data []byte } 这类含引用字段的切片完全无效——新切片里的指针、子切片仍指向原底层数组。
- 修改
copied[i].Data[0] = 99,原切片对应项同步变化 - 并发场景下极易引发 data race,尤其当副本传入 goroutine 后原切片被修改
- 仅当元素类型是纯值类型(
[]int、[]string、或不含引用字段的struct)时,copy才等价于“安全副本”
性能接近 memmove,但行为由编译器硬编码保障
copy 不是普通函数调用,编译器在编译期将其降级为底层内存操作(amd64 下多数走 memmove 汇编实现),小数据走线性指令,大数据自动启用 SIMD 加速。
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
- 零堆分配、O(n) 时间复杂度,比手动 for 循环略快(省去边界检查和索引计算开销)
- 支持重叠区域复制(如
copy(s[1:], s)实现左移),语义等价于 C 的memmove,不是memcpy - 不检查元素是否可寻址或是否含 unexported 字段——它只按字节搬,所以能复制任何切片,包括含 channel 或 func 的 struct(只要类型允许切片化)
别和 io.Copy 混用,它们解决完全不同的问题
copy 操作内存切片,io.Copy 在 io.Reader 和 io.Writer 之间流式搬运字节。名字相似,但类型系统、使用场景、错误处理机制毫无交集。
立即学习“go语言免费学习笔记(深入)”;
- 误把
io.Copy当成切片复制工具?编译直接报错:cannot use [...] as io.Reader -
io.Copy默认 32KB 缓冲,适合文件/网络;copy无缓冲概念,一次到位 - 需要深拷贝嵌套结构?
copy做不了,io.Copy更做不了——得用 gob、json 或手写递归逻辑
copy 的“安全”仅限于内存不越界,不等于逻辑隔离**。你复制完一个 []map[string]int,看起来没报错,但两个切片里的 map 仍共享同一底层哈希表——改一个,另一个的遍历顺序甚至长度都可能突变。


















