如何使用Go中的切片副本?

如何使用Go中的切片副本?,go,slice,Go,Slice,mapArray是float32的二维切片。我制作了一个副本,这样我就可以在不修改mapArray的情况下处理副本。然而,事实并非如此。将值赋给Origin将修改mapArray origins := it.Empty2DArray(len(mapArray)) copy(origins, mapArray) origins[5][5] = -1 这样做会使mapArray[5][5]的原始值变为-1 我如何制作切片的真正独立副本 谢谢 编辑: //Empty2DArray返回一个归零的二维数

mapArray是float32的二维切片。我制作了一个副本,这样我就可以在不修改mapArray的情况下处理副本。然而,事实并非如此。将值赋给
Origin
将修改
mapArray

origins := it.Empty2DArray(len(mapArray))
copy(origins, mapArray)
origins[5][5] = -1
这样做会使
mapArray[5][5]
的原始值变为-1

我如何制作切片的真正独立副本

谢谢

编辑:

//Empty2DArray返回一个归零的二维数组。
func Empty2DArray(数组化整型)[]浮点32{
emptyArray:=make([]float32,arraySize)
对于y:=0;y
二维切片就是切片的切片。在函数中,分配一个片来保存其他片,然后为每个片分配内存来保存该行数据。要复制这个,您需要复制所有这些数据行加上整个切片

当您说
copy(origins,mapArray)
时,您真正要做的是复制指向原始数据的指针片段。但是,您不会复制原始数据

我建议不要使用嵌套for循环来复制子切片,而是使用一维切片并创建包装函数来索引到其中。这样内存效率更高,您可以使用内置的
copy

以下是一份:

如果您坚持使用2D float32数组,则:


谢谢,但是我添加了一个函数,我创建了一个新的切片,已经是make了,所以我已经这样做了,除非有什么我没有发现的。你这是什么意思?为什么使用指针而不是标准变量。不管怎么说,都测试了,没有指针和,当我的程序完成时,所需的时间和内存消耗增加了10倍,没有谎言。从200MB内存到2GB,从几秒钟到10秒钟。我将运行pprof,看看有什么问题。我看到直接变量和指针变量的内存节省可以忽略不计。
// Empty2DArray returns a zeroed 2D array.
func Empty2DArray(arraySize int) [][]float32 {
    emptyArray := make([][]float32, arraySize)
    for y := 0; y < arraySize; y++ {
        row := make([]float32, arraySize)
        for x := 0; x < arraySize; x++ {
            row[x] = 0
        }
        emptyArray[y] = row
    }
    return emptyArray
}
package main

import "fmt"

type squareMat struct {
    size int
    data []float32
}

func newSquareMat(size int) *squareMat {
    return &squareMat{
        size: size,
        data: make([]float32, size*size),
    }
}

func (s *squareMat) get(i, j int) float32 {
    return s.data[i+j*s.size]
}

func (s *squareMat) set(i, j int, to float32) {
    s.data[i+j*s.size] = to
}

func (s *squareMat) copy() *squareMat {
    c := newSquareMat(s.size)
    copy(c.data, s.data)
    return c
}

func main() {
    m := newSquareMat(5)
    m.set(2, 3, 1.5)
    n := m.copy()
    n.set(2, 3, 99)
    fmt.Println(m.get(2, 3))
    fmt.Println(n.get(2, 3))
}
package main

import "fmt"

func copy2D(x [][]float32) [][]float32 {
    c := make([][]float32, len(x))
    for i := range c {
        c[i] = make([]float32, len(x[i]))
        copy(c[i], x[i])
    }
    return c
}

func main() {
    a := [][]float32{
        []float32{1, 2, 3},
        []float32{4, 5, 6},
        []float32{7, 8, 9},
    }
    b := copy2D(a)
    b[1][1] = 99
    fmt.Println(a)
    fmt.Println(b)
}