首页 > 文章列表 > 内置函数copy()是否进行的是浅拷贝?

内置函数copy()是否进行的是浅拷贝?

303 2024-02-06
问题内容

下面的代码:

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

    dst = src // shallow copy
    fmt.Println(&dst[0]) //0xc00001c210

    copy(dst, src) // shallow copy
    fmt.Println(&dst[0]) //0xc00001c210
}

使用简单的赋值和 copy() 内置函数执行浅复制

copy() 内置函数的用途是什么?因为赋值操作正在执行浅复制..


正确答案


您看到相同内存地址的原因是由于将 dst 切片替换为 src - 这使得 copy 成为无操作。由于 dstsrc 切片指向同一内存,任何修改都会影响这两个切片。通常,您希望将 copy 到不同的切片/内存,以便可以独立修改切片。

copy 实际上是一个浅拷贝。它仅将源切片直接引用的内存复制到目标切片引用的内存。它不会跟随指针并克隆下面的结构(如果有的话)。

另一个用指针突出显示这一点的示例:

package main

import "fmt"

type data struct {
    num int
}

func main() {
    src := []*data{&data{}, &data{}}
    dst := make([]*data, 2)
    copy(dst, src)
    fmt.Printf("src: %p : %#vn", &src[0], src)
    fmt.Printf("dst: %p : %#vn", &dst[0], dst)
}

// Outputs:
// src: 0xc000014260 : []*main.data{(*main.data)(0xc00001c030), (*main.data)(0xc00001c038)}
// dst: 0xc000014270 : []*main.data{(*main.data)(0xc00001c030), (*main.data)(0xc00001c038)}

这显示:

  • src 和 dst 切片使用不同的内存(不同的指针)
  • 复制的结构是相同的(相同的指针,不是克隆的)。