为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 Go 中处理切片的副本?

如何在 Go 中处理切片的副本?

Go
胡说叔叔 2023-03-21 15:56:37
mapArray 是 float32 的二维切片。我复制了它,这样我就可以在不修改 mapArray 的情况下处理副本。然而,事实并非如此。Origin为modifies赋值mapArray。origins := it.Empty2DArray(len(mapArray))copy(origins, mapArray)origins[5][5] = -1这样做mapArray[5][5]会使 -1 而不是其原始值。我如何制作切片的真正独立副本?谢谢。编辑:// 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}
查看完整描述

1 回答

?
慕村9548890

TA贡献1884条经验 获得超4个赞

二维切片是切片的切片。在您的函数中,您分配一个切片来保存其他切片,然后为每个切片分配内存来保存该行数据。要复制它,您需要复制所有这些数据行以及整个切片。

当你说 时copy(origins, mapArray),你真正做的是复制一份指向原始数据的指针。但是,您不复制原始数据。

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

这是我会做的示例


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))

}

如果你坚持使用 2D float32 数组,这里是复制它的方法


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)

}


查看完整回答
反对 回复 2023-03-21
  • 1 回答
  • 0 关注
  • 151 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号