Go language to explain deep copy and shallow copy

We will often copy one variable to another variable in development, then this process may be a shallow copy, so today I will help you distinguish the difference between these two copies and the specific difference.

1. Concept

1. Deep Copy:

What is copied is the data itself, creating a new kind of object. The newly created object does not share memory with the original object. The newly created object opens up a new memory address in memory, and the new object value will not affect the original object value when modified. Since the memory addresses are different, when the memory addresses are released, they can be released separately.

By default, all data of value type is deep copy, Array, Int, String, Struct, Float, Bool.

2. Shallow Copy:

The data address is copied, and only the pointer of the pointed object is copied. At this time, the memory address pointed by the new object and the old object are the same, and the old object will also change when the new object value is modified. When the memory address is released, the memory address is released at the same time.

Reference type data, all are shallow copy by default, Slice, Map.

Second, the essential difference:

Whether to actually get (copy) object entities, not references.

3. How to understand?

Here is an example. For example, when P2 copies P1 and changes the P1 attribute, observe whether the attribute of P2 will change.

1. The properties of P2 have changed, indicating that this is a shallow copy, and the memory in the heap is still the same value.

p2=&p1 // 浅拷贝,p2为指针,p1和p2共用一个内存地址

2. The properties of P2 have not changed, indicating that this is a deep copy, and the memory in the heap is a different value.

p2=p1 // 深拷贝,生成两个内存地址 

4. Demo example:

Deep copy example:

package main

import (
   "fmt"
)

// 定义一个Robot结构体
type Robot struct {
   Name  string
   Color string
   Model string
}

func main() {
   fmt.Println("深拷贝 内容一样,改变其中一个对象的值时,另一个不会变化。")
   robot1 := Robot{
      Name:  "小白-X型-V1.0",
      Color: "白色",
      Model: "小型",
   }
   robot2 := robot1
   fmt.Printf("Robot 1:%s\t内存地址:%p \n", robot1, &robot1)
   fmt.Printf("Robot 2:%s\t内存地址:%p \n", robot2, &robot2)

   fmt.Println("修改Robot1的Name属性值")
   robot1.Name = "小白-X型-V1.1"

   fmt.Printf("Robot 1:%s\t内存地址:%p \n", robot1, &robot1)
   fmt.Printf("Robot 2:%s\t内存地址:%p \n", robot2, &robot2)

}

operation result:

深拷贝 内容一样,改变其中一个对象的值时,另一个不会变化。
Robot 1:{小白-X型-V1.0 白色 小型}      内存地址:0xc000072330
Robot 2:{小白-X型-V1.0 白色 小型}      内存地址:0xc000072360
修改Robot1的Name属性值
Robot 1:{小白-X型-V1.1 白色 小型}      内存地址:0xc000072330
Robot 2:{小白-X型-V1.0 白色 小型}      内存地址:0xc000072360

In the deep copy, we can see that the address of Robot1 and the memory address of Robot2 are different. When the Name property of Robot1 is modified, Robot2 will not change.

We will introduce shallow copy in two ways.

Shallow copy example 1:

package main

import (
   "fmt"
)

// 定义一个Robot结构体
type Robot struct {
   Name  string
   Color string
   Model string
}

func main() {

   fmt.Println("浅拷贝 内容和内存地址一样,改变其中一个对象的值时,另一个同时变化。")
   robot1 := Robot{
      Name:  "小白-X型-V1.0",
      Color: "白色",
      Model: "小型",
   }
   robot2 := &robot1
   fmt.Printf("Robot 1:%s\t内存地址:%p \n", robot1, &robot1)
   fmt.Printf("Robot 2:%s\t内存地址:%p \n", robot2, robot2)

   fmt.Println("在这里面修改Robot1的Name和Color属性")
   robot1.Name = "小黑-X型-V1.1"
   robot1.Color = "黑色"

   fmt.Printf("Robot 1:%s\t内存地址:%p \n", robot1, &robot1)
   fmt.Printf("Robot 2:%s\t内存地址:%p \n", robot2, robot2)

}

Operation result 1:

浅拷贝 内容和内存地址一样,改变其中一个对象的值时,另一个同时变化。
Robot 1:{小白-X型-V1.0 白色 小型}      内存地址:0xc000062330
Robot 2:&{小白-X型-V1.0 白色 小型}     内存地址:0xc000062330
在这里面修改Robot1的Name和Color属性
Robot 1:{小黑-X型-V1.1 黑色 小型}      内存地址:0xc000062330
Robot 2:&{小黑-X型-V1.1 黑色 小型}     内存地址:0xc000062330

In the shallow copy, we can see that the memory addresses of Robot1 and Robot2 are the same. When the attributes of one of the objects are modified, the other will also change.

Shallow copy example 2:

package main

import (
   "fmt"
)

// 定义一个Robot结构体
type Robot struct {
   Name  string
   Color string
   Model string
}

func main() {

   fmt.Println("浅拷贝 使用new方式")
   robot1 := new(Robot)
   robot1.Name = "小白-X型-V1.0"
   robot1.Color = "白色"
   robot1.Model = "小型"

   robot2 := robot1
   fmt.Printf("Robot 1:%s\t内存地址:%p \n", robot1, robot1)
   fmt.Printf("Robot 2:%s\t内存地址:%p \n", robot2, robot2)

   fmt.Println("在这里面修改Robot1的Name和Color属性")
   robot1.Name = "小蓝-X型-V1.2"
   robot1.Color = "蓝色"

   fmt.Printf("Robot 1:%s\t内存地址:%p \n", robot1, robot1)
   fmt.Printf("Robot 2:%s\t内存地址:%p \n", robot2, robot2)
}

operation result:

浅拷贝 使用new方式
Robot 1:&{小白-X型-V1.0 白色 小型}     内存地址:0xc000068330
Robot 2:&{小白-X型-V1.0 白色 小型}     内存地址:0xc000068330
在这里面修改Robot1的Name和Color属性
Robot 1:&{小黑-X型-V1.2 黑色 小型}     内存地址:0xc000068330
Robot 2:&{小黑-X型-V1.2 黑色 小型}     内存地址:0xc000068330

The new operation, robot2: = robot1, looks like a deep copy, but it is actually a shallow copy. The two pointers of robot2 and robot1 share the same memory address.

 

Published 160 original articles · 21 praises · 240,000 views

Guess you like

Origin blog.csdn.net/guichenglin/article/details/105601886