You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言slice的copy函数实现机制及执行结果疑问

Go语言copy函数的行为解析

先看你的测试代码:

package main

import "fmt"

func main() {
    arr := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    copy(arr[4:], arr[2:])
    fmt.Println(arr)
}

为什么实际输出和预期不符?

你预期输出[1, 2, 3, 4, 3, 4, 3, 4, 3, 4],但实际得到[1, 2, 3, 4, 3, 4, 5, 6, 7, 8],核心原因是误解了copy函数处理重叠切片的逻辑。

copy函数的核心规则

  1. 复制元素个数:copy(dst, src)会取两个切片长度的最小值作为实际复制的元素数量。
    • 你的例子中,arr[4:]长度是6(索引4到9),arr[2:]长度是8(索引2到9),所以实际复制6个元素。
  2. 重叠切片的安全处理:当源切片和目标切片指向同一个底层数组且区域重叠时,copy函数会保证先读取所有需要的源元素,再写入目标位置,或通过调整复制顺序(从左到右/从右到左)避免覆盖未读取的源数据。

你的例子具体执行过程

原数组:[1,2,3,4,5,6,7,8,9,10]

  • 需要复制的源元素是arr[2]到arr[7](共6个):3,4,5,6,7,8
  • 依次写入arr[4]到arr[9]:
    • arr[4] = 3
    • arr[5] = 4
    • arr[6] = 5(此时原arr[4]的5还没被覆盖,源元素已提前读取)
    • arr[7] = 6
    • arr[8] = 7
    • arr[9] = 8
      最终数组就变成了[1,2,3,4,3,4,5,6,7,8]。

copy函数的实现逻辑

Go的copy函数底层会判断源切片和目标切片的位置关系:

  • 如果目标切片起始索引 ≥ 源切片起始索引(目标在源右侧,如你的例子),就从左到右依次复制,确保源元素在被覆盖前已读取。
  • 如果目标切片起始索引 < 源切片起始索引(目标在源左侧),则从右到左复制,避免覆盖后续要读取的源元素。

内容的提问来源于stack exchange,提问作者Ebenezer Rahul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 10:22:38