go与python的深浅copy对比

55 篇文章 5 订阅

go

  1. 在go语言中值类型赋值都是深拷贝,引用类型一般都是浅拷贝
  2. 其本质就是,深拷贝会拷贝数据,而浅拷贝只会拷贝内存的地址,所有就会出现,像slice那样修改底层数组的值,slice的值也跟着改动。

深拷贝

修改a的值b不变,说明是值的拷贝

func main() {
    var a = 123
    b := a
    fmt.Println(a, b)
    a = 456
    fmt.Println(a, b)
}

浅拷贝

修改a的值,b的值也跟着修改了,原因是两个slice指向同一个内存地址,所以得出记录slice拷贝是浅拷贝

func main() {
    a := []int{1, 2, 3}
    b := a
    fmt.Println(a, b)
    a[0] = 1000
    fmt.Println(a, b)
}

slice深拷贝

可以通过内置的copy函数实现,或append导致扩容形成一个新的切片

func main() {
    a := []int{1, 2, 3}
    b := make([]int, 0)
    b = append(b, a[:]...)
    fmt.Println(a, b)
    a[1] = 1000
    fmt.Println(a, b)
    fmt.Printf("%p,%p", a, b)
}

func main() {
    slice1 := []int{1, 2, 3, 4, 5}
    slice2 := []int{5, 4, 3}

    copy(slice2, slice1) // 只会复制slice1的前3个元素到slice2中
    fmt.Println(slice1, slice2)
    copy(slice1, slice2) // 只会复制slice2的3个元素到slice1的前3个位置
    fmt.Println(slice1, slice2)
}

总结

  1. 赋值操作:

    1. 如果是值类型,就会产生深拷贝
    2. 如果是引用类型,就会产生浅拷贝
  2. 深浅拷贝的区别:

    1. 深拷贝:光拷贝值,地址不相关。拷贝结束两变量互不影响。
    2. 浅拷贝:拷贝地址。两变量指向同一地址。拷贝结束也相关,改变一个,另一个也跟着变。

python

有点小不同:

  1. 对于不可变类型:不论深浅拷贝,都是引用。
  2. 浅拷贝:只复制最外层的结构,除最外层其余的直接将其地址引用过来。
  3. 深拷贝:全部数据/结构都进行复制,(除不可变类型)增大数据独立性 ,如果深拷贝中,只要发现复制数据中有一个不是不可变类型就重新创建。
from copy import deepcopy, copy


def echo_addr(interface):
    return hex(id(interface))


def init():
    # 赋值
    l1 = [1, 2, 3]
    l2 = l1
    print(echo_addr(l1), echo_addr(l2))
    # 0x2ca7d68e600 0x2ca7d68e600
    print(echo_addr(l1[0]), echo_addr(l2[0]))
    # 0x7ff8b3451710 0x7ff8b3451710
    l2[0] = 5
    print(l1, l2)
    # [5, 2, 3] [5, 2, 3]


def cp():
    # 浅拷贝
    l1 = [1, 2, 3]
    l2 = copy(l1)
    print(echo_addr(l1), echo_addr(l2))
    # 0x2950198e700 0x2950198e540
    print(echo_addr(l1[0]), echo_addr(l2[0]))
    # 0x7ff8b3451710 0x7ff8b3451710
    l2[0] = 5
    print(l1, l2)
    # [1, 2, 3] [5, 2, 3]


def deep_cp():
    # 深拷贝
    l1 = [1, 2, 3]
    l2 = deepcopy(l1)
    print(echo_addr(l1), echo_addr(l2))
    # 0x2059c9ce740 0x2059c9ce580
    print(echo_addr(l1[0]), echo_addr(l2[0]))
    # 0x7ff8b3451710 0x7ff8b3451710
    l2[0] = 5
    print(l1, l2)
    # [1, 2, 3] [5, 2, 3]


# init()
# cp()
deep_cp()


def cpcpcpcpcp():
    a = 1
    b = copy(a)
    c = deepcopy(a)

    print(echo_addr(a), echo_addr(b), echo_addr(c))
    # 0x7ff88bce1710 0x7ff88bce1710 0x7ff88bce1710

# cpcpcpcpcp()

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Generalzy

文章对您有帮助,倍感荣幸

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值