Golang多维切片复制

8

我正在尝试制作一个多维切片的克隆版本,因为当我改变复制的切片中的元素时,原始切片中的元素也被覆盖了。

唯一对我有效的方法是:

duplicate := make([][]int, len(matrix))
for i := 0; i < len(matrix); i++ {
    duplicate[i] = make([]int, len(matrix[0]))
    for j := 0; j < len(matrix[0]); j++ {
        duplicate[i][j] = matrix[i][j]
    }
}

有没有更短或更有效的方法来达到同样的结果?谢谢。


1
您可以使用 https://golang.org/pkg/builtin/#copy 来消除内部 for 循环,但我不确定其效率是否更高。我猜内置函数会更好。 - RayfenWindspear
谢谢,工作正常 ;) 至少少写一些。 - Serghei Luchianenco
我可能稍后会进行基准测试,因为我很好奇它与其他的比较如何。 - RayfenWindspear
期待你的基准测试 ;) 如果你能告诉我如何自己进行基准测试,那就太好了...谢谢 - Serghei Luchianenco
2个回答

21
你可以在内部循环中使用copy(这应该更有效),在外部循环中使用range(这会使代码更加美观)。
duplicate := make([][]int, len(matrix))
for i := range matrix {
    duplicate[i] = make([]int, len(matrix[i]))
    copy(duplicate[i], matrix[i])
}
如果你的目标是效率,那么提前分配更多可能会是一个明智的选择。虽然这不会让代码更易读,但如果你经常这样做,它会导致更高效的代码。这段代码假设你至少有一行,并且所有行的长度都相同。你需要为此添加测试。
如果您的目标是效率,可能有意义在一开始时进行更多的分配。这不会使代码更易读,但如果您经常这样做,则会导致更高效的代码。此代码假设您至少拥有一行,并且所有行的长度相同。您需要添加针对此内容的测试。
n := len(matrix)
m := len(matrix[0])
duplicate := make([][]int, n)
data := make([]int, n*m)
for i := range matrix {
    start := i*m
    end := start + m
    duplicate[i] = data[start:end:end]
    copy(duplicate[i], matrix[i])
}

根据您所做的事情,使用仅一个切片实现的“矩阵类型”可能是有意义的。尽管切片嵌套切片更加易于操作,但它并不是最高效的数据结构。


在决定是否需要效率之前,请确保通过分析查看您花费了大量时间进行复制。然后,在确定这确实是一个热点之后,开始运行基准测试。有关详细信息,请参见https://golang.org/pkg/testing/#hdr-Benchmarks


哈哈,如果我知道我会得到这么多简单的声望,我本来就会自己写一个完整的答案了。不过还是要赞一下,因为这确实是一个非常好的答案。 - RayfenWindspear
顺便提一下,关于使用单个切片的警告评论。如果您要修改矩阵的xy长度,尝试使用平面矩阵是一个不好的想法。 - RayfenWindspear
好的,通过添加一个容量已经修复了这个问题。不过,这意味着任何一个切片都可以防止整个东西被垃圾回收。虽然这会减少收集器的工作量,但也可能导致无法访问的数据没有被回收。 - Stephen Weinberg

-1

你可以通过gob将其往返转换:

package main

import (
   "bytes"
   "encoding/gob"
   "fmt"
)

func sliceCopy(in, out interface{}) {
   buf := new(bytes.Buffer)
   gob.NewEncoder(buf).Encode(in)
   gob.NewDecoder(buf).Decode(out)
}

func main() {
   a := [][]int{
      {1, 2, 3}, {4, 5, 6}, {7, 8, 9},
   }
   var b [][]int
   sliceCopy(a, &b)
   fmt.Println(b)
}

https://golang.org/pkg/encoding/gob


1
一个可以复制任意数据的好解决方案,但对于这种简单情况效率非常低。 - Phani Rithvij

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接