golang中数组的子集

时间:2015-01-25 04:38:33

标签: python arrays pointers go

我试图在python

中写下以下行的等价物

H = [e for e in G if condition(e)]

这是我的示例代码。基本上我只是尝试使用getter函数(G.get)来获取G的子集。所以我想我希望arr2成为一个新数组但包含相同的对象。

package main

import "fmt"

type Object struct {
    x int
}

type Group []Object

func (G *Group) get() (H []Object) {
    for _,v := range *G {
        H = append(H,v)
    }
    return
}

func main() {
    arr := make(Group,1)
    arr[0].x = 1
    fmt.Println(arr)
    arr2 := arr.get()
    arr[0].x = 3
    fmt.Println(arr)
    fmt.Println(arr2)
}

编译并运行并给我

[{1}]
[{3}]
[{1}]

我的问题是"为什么arr2不包含与arr相同的对象实例?"我相信我理解make只会实例化Group这意味着它包含一个Object。但是for循环不应该创建一个新的Object吗?

感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

这个更简单的代码片段显示了正在发生的事情:

var a Object
a.x = 1
b := a
fmt.Println(a, b) // prints {1} {1}
b.x = 2
fmt.Println(a, b) // prints {1} {2}

playground example

声明b := a将变量Object中的a值复制到变量b。现在有两个值的副本。改变一个不会改变另一个。

这与Python不同,其中赋值复制对值的引用。

问题中的循环还会复制值:

for _,v := range *G {
    H = append(H,v)
}

变量v是来自*G的切片元素的副本。 v的副本会附加到切片H。有三个独立的Object值:切片*G中的值,v中的值和切片H中的值。

如果您希望切片全部引用相同的Object值,则在切片中存储指向Object值的指针:

type Group []*Object

arr := make(Group, 1)
arr[0] = &Object{x: 1}
fmt.Println(arr[0].x)  // prints 1
arr2 := arr.get()
arr[0].x = 3
fmt.Println(arr[0].x)  // prints 3
fmt.Println(arr2[0].x) // prints 3

playground example