copy()内置函数执行浅拷贝吗?

huangapple go评论92阅读模式
英文:

Does copy() builtin function perform shallow 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

    dst = src // 浅拷贝
    fmt.Println(&dst[0]) //0xc00001c210

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

通过简单的赋值和copy()内置函数执行浅拷贝。

copy()内置函数的目的是什么?因为赋值操作执行的是浅拷贝。

英文:

Below code:

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
}

performs shallow copy using a simple assignment and copy() builtin function

What is the purpose of copy() builtin function? Because assignment operation is performing shallow copy..

答案1

得分: 2

你看到相同的内存地址是因为用src替换了dst切片,这使得copy操作没有实际效果。由于dstsrc切片指向相同的内存,任何修改都会影响到两个切片。通常情况下,你希望将数据复制到不同的切片或内存中,以便可以独立地修改切片。

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 : %#v\n", &src[0], src)
	fmt.Printf("dst: %p : %#v\n", &dst[0], dst)
}

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

这个例子展示了:

  • srcdst切片使用不同的内存(不同的指针)
  • 复制的结构体是相同的(相同的指针,没有克隆)。
英文:

The reason you are seeing the same memory address is due to replacing the dst slice with src - this makes copy a no-op. With the dst and src slices pointing to the same memory, any modification will affect both slices. Typically you want to copy to a different slice/memory so slices can be modified independently.

copy is effectively a shallow copy. It only copies the memory directly referenced by the source slice to the memory referenced by the destination slice. It will not follow pointers and clone the structs underneath (if there are any).

Another example that highlights this with pointers:

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 : %#v\n", &src[0], src)
	fmt.Printf("dst: %p : %#v\n", &dst[0], dst)
}

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

This shows:

  • The src and dst slices are using different memory (different pointers)
  • The structs copied are identical (same pointers, not cloned).

huangapple
  • 本文由 发表于 2023年1月9日 14:44:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/75053916.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定