Go结构体之间的深拷贝、浅拷贝、指针直接赋值

1、大白话翻译

术语

翻译

深拷贝

- 这就像是完全复制了一个文件夹,包括里面的所有子文件夹和文件

- 你和别人有两个完全独立的文件夹,修改自己的不会影响对方

- 内存中会保存两份完整的配置数据

浅拷贝

- 这像是复制了一个文件夹,但里面的子文件夹仍然是快捷方式

- 从 a 结构体可以看到,它包含一个指针字段: *aa

- 浅拷贝会复制结构体本身,但不会复制指针指向的内容address string 的值

- 你和别人有两个不同的文件夹,但里面的子文件夹还是指向同一个地方

直接赋值

- 这就像是把一个文件夹的快捷方式复制给别人

- 两个人通过不同的快捷方式打开的是 同一个文件夹

- 如果别人修改了文件夹里的内容,你也会看到变化

- 内存中只保存了一份配置数据

2、案例展示

package main

import "fmt"

// 结构体aa - 内部结构体
type aa struct {
    address string  // 注意:Go中字符串类型是string
}

// 结构体a - 外部结构体,包含aa指针
type a struct {
    aaObj *aa  // aaObj
}

// 结构体bb - 内部结构体(类似于aa)
type bb struct {
    address string
}

// 结构体b - 外部结构体,包含bb指针
type b struct {
    bbObj *bb
}

func main() {
    // 创建原始数据
    original := &a{
        aaObj: &aa{
            address: "原始地址",
        },
    }
    
    // 1. 指针直接赋值示例
    fmt.Println("1. 指针直接赋值示例:")
    pointerCopy := original  // 直接赋值指针
    pointerCopy.aaObj.address = "修改后的地址"
    // 注意:original的地址也会被修改,因为它们指向同一个aaObj
    fmt.Printf("original地址: %s\n", original.aaObj.address)  // 输出: 修改后的地址
    fmt.Printf("pointerCopy地址: %s\n\n", pointerCopy.aaObj.address)  // 输出: 修改后的地址
    
    // 重置原始数据
    original = &a{
        aaObj: &aa{
            address: "原始地址",
        },
    }
    
    // 2. 浅拷贝示例
    fmt.Println("2. 浅拷贝示例:")
    shallowCopy := &a{}  // 创建新的a结构体
    *shallowCopy = *original  // 浅拷贝:复制a结构体,但aaObj指针仍指向同一个对象
    shallowCopy.aaObj.address = "修改后的地址"
    // 注意:original的地址也会被修改,因为它们的aaObj指向同一个对象
    fmt.Printf("original地址: %s\n", original.aaObj.address)  // 输出: 修改后的地址
    fmt.Printf("shallowCopy地址: %s\n\n", shallowCopy.aaObj.address)  // 输出: 修改后的地址
    
    // 重置原始数据
    original = &a{
        aaObj: &aa{
            address: "原始地址",
        },
    }
    
    // 3. 深拷贝示例
    fmt.Println("3. 深拷贝示例:")
    deepCopy := &a{
        aaObj: &aa{  // 创建新的aa结构体
            address: original.aaObj.address,  // 复制地址值
        },
    }
    deepCopy.aaObj.address = "修改后的地址"
    // 注意:original的地址不会被修改,因为它们指向不同的aaObj对象
    fmt.Printf("original地址: %s\n", original.aaObj.address)  // 输出: 原始地址
    fmt.Printf("deepCopy地址: %s\n", deepCopy.aaObj.address)  // 输出: 修改后的地址
}

消息盒子

# 暂无消息 #

只显示最新10条未读和已读信息