是否相当于在golang中使用“复制”或“附加”切片类型

问题描述 投票:0回答:3
    a := []byte{1, 2, 3}
    // Method: 1
    b := make([]byte, len(a))
    copy(b, a)
    // Method: 2
    c := append([]byte(nil), a...)

问:方法2是不是比方法1更加简洁高效?

问:模式2和模式1是否等价,都是深拷贝?

谢谢您的帮助

go slice
3个回答
8
投票

方法 1 更精确 - 因为它准确分配所需的切片大小并填充它。

方法 2 的追加将以 8 为单位分配一块容量(可能取决于您的架构)。因此,这 3 个初始项将被复制到大小为 8 的后备数组中:

https://go.dev/play/p/C2nPQFflsM2


1
投票

如果修复了第二种方法的实现,则可以使用这两种方法。

// Method 1
b := make([]byte, len(a))
copy(b, a)

// Method 2
c := make([]byte, 0, len(a))
c = append(c, a...)

https://go.dev/play/p/rkMmIsSaHVW


0
投票

为了补充已接受的答案,在示例中我们以 8 字节为单位进行分配。对于不是 8 字节(或 32 位架构上的 4 字节)倍数的数组大小,我们将稍微扩展容量。也就是说,如果你尝试:

    a := []int{1, 2, 3, 4}
    // Method: 1
    b := make([]int32, len(a))
    copy(b, a)
    // Method: 2
    c := append([]int32(nil), a...)

在这两种情况下您都会获得相同的长度和容量,因为

4 * 4B = 16B = 2 * 8B

我在这里猜测了一点,但这可能是针对较小类型的性能优化 - 在 64 位架构上分配 64 位而不是较小的块要快得多。

一个更通用的例子: https://go.dev/play/p/u-28butfj0L

© www.soinside.com 2019 - 2024. All rights reserved.