为什么我不能在golang中拷贝一份拷贝?
我需要做一个切片的副本去阅读文档有一个复制function在我的处置。
复制内置函数将来自源片段的元素复制到目标片段中。 (作为特殊情况,它也会将字节中的字节复制到一个字节片段中。)源和目标可能会重叠。 复制返回复制的元素的数量,这将是len(src)和len(dst)的最小值。
但是当我这样做
arr := []int{1, 2, 3} tmp := []int{} copy(tmp, arr) fmt.Println(tmp) fmt.Println(arr)
我的tmp
是空的,因为它以前(我甚至试图使用arr,tmp):
[] [1 2 3]
你可以去操场上检查它。 那么为什么我不能复制一个切片?
内置copy(dst, src)
拷贝min(len(dst), len(src))
元素。
所以如果你的dst
是空的( len(dst) == 0
),什么都不会被复制。
尝试tmp := make([]int, len(arr))
( Go Playground ):
arr := []int{1, 2, 3} tmp := make([]int, len(arr)) copy(tmp, arr) fmt.Println(tmp) fmt.Println(arr)
产量(如预期):
[1 2 3] [1 2 3]
不幸的是,这在builtin
包中没有logging,但是在Go语言规范中有logging:追加和复制片 :
复制元素的数量是
len(src)
和len(dst)
的最小值。
编辑:
最后, copy()
的文档已经更新了,现在它包含了一个事实,即源和目标的最小长度将被复制:
复制返回复制的元素的数量,这将是len(src)和len(dst)的最小值 。
如果您的切片尺寸相同, 则可以工作 :
arr := []int{1, 2, 3} tmp := []int{0, 0, 0} i := copy(tmp, arr) fmt.Println(i) fmt.Println(tmp) fmt.Println(arr)
会给:
3 [1 2 3] [1 2 3]
从“ 切片:使用和内部 ”:
复制function支持在不同长度的片段之间进行复制( 它只复制到less量的元素 )
通常的例子是:
t := make([]byte, len(s), (cap(s)+1)*2) copy(t, s) s = t
另一个简单的方法是使用append
来分配进程中的slice。
arr := []int{1, 2, 3} tmp := []int{} tmp = append(tmp, arr...) // Notice the ... splat fmt.Println(tmp) fmt.Println(arr)
产量(如预期):
[1 2 3] [1 2 3]
所以复制数组arr
的简写为tmp := append([]int{}, arr...)
copy()运行dst和src的最小长度,所以你必须初始化dst到所需的长度。
A := []int{1, 2, 3} B := make([]int, 3) copy(B, A) C := make([]int, 2) copy(C, A) fmt.Println(A, B, C)
输出:
[1 2 3] [1 2 3] [1 2]
您可以使用append()将所有元素初始化并复制到一个无切片中。
x := append([]T{}, []...)
例:
A := []int{1, 2, 3} B := append([]int{}, A...) C := append([]int{}, A[:2]...) fmt.Println(A, B, C)
输出:
[1 2 3] [1 2 3] [1 2]
与分配+ copy()相比,对于大于1,000个元素,使用append。 其实低于1000的差别可能会被忽略,除非你有很多的切片,否则就是一个经验法则。
BenchmarkCopy1-4 50000000 27.0 ns/op BenchmarkCopy10-4 30000000 53.3 ns/op BenchmarkCopy100-4 10000000 229 ns/op BenchmarkCopy1000-4 1000000 1942 ns/op BenchmarkCopy10000-4 100000 18009 ns/op BenchmarkCopy100000-4 10000 220113 ns/op BenchmarkCopy1000000-4 1000 2028157 ns/op BenchmarkCopy10000000-4 100 15323924 ns/op BenchmarkCopy100000000-4 1 1200488116 ns/op BenchmarkAppend1-4 50000000 34.2 ns/op BenchmarkAppend10-4 20000000 60.0 ns/op BenchmarkAppend100-4 5000000 240 ns/op BenchmarkAppend1000-4 1000000 1832 ns/op BenchmarkAppend10000-4 100000 13378 ns/op BenchmarkAppend100000-4 10000 142397 ns/op BenchmarkAppend1000000-4 2000 1053891 ns/op BenchmarkAppend10000000-4 200 9500541 ns/op BenchmarkAppend100000000-4 20 176361861 ns/op
Go编程语言规范
追加和复制切片
函数拷贝将slice元素从源src复制到目标dst,并返回复制元素的数量。 两个参数必须具有相同的元素typesT,并且必须可分配给types为[] T的片段。 复制元素的数量是len(src)和len(dst)的最小值。 作为一种特殊情况,copy也接受一个可指派给types为[] byte的目标参数,并使用一个stringtypes的源参数。 这种forms将string中的字节复制到字节片段中。
copy(dst, src []T) int copy(dst []byte, src string) int
tmp
需要足够的空间来存放arr
。 例如,
package main import "fmt" func main() { arr := []int{1, 2, 3} tmp := make([]int, len(arr)) copy(tmp, arr) fmt.Println(tmp) fmt.Println(arr) }
输出:
[1 2 3] [1 2 3]