Golang中数组的子集

3

我正在尝试用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`。但是循环不应该创建一个新的 `Object` 吗?
感谢您的帮助!
1个回答

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会将变量a中的Object值复制到变量b中。现在有两个值的副本。更改一个值不会影响另一个值。

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

问题中的循环也会复制这些值:

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

变量v是从*G切片元素的副本。将v的副本附加到切片H。有三个独立的对象值:切片*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

示例代码

(注:该链接为示例代码的网址)

很棒的解释!了解:=复制值的知识非常好。此外,您是否知道有更好的方法可以执行[e for e in G if condition(e)]吗? - Travis

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