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是否等价,都是深拷贝?
谢谢您的帮助
方法 1 更精确 - 因为它准确分配所需的切片大小并填充它。
方法 2 的追加将以 8 为单位分配一块容量(可能取决于您的架构)。因此,这 3 个初始项将被复制到大小为 8 的后备数组中:
如果修复了第二种方法的实现,则可以使用这两种方法。
// Method 1
b := make([]byte, len(a))
copy(b, a)
// Method 2
c := make([]byte, 0, len(a))
c = append(c, a...)
为了补充已接受的答案,在示例中我们以 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