subset of array in golang

huangapple go评论93阅读模式
英文:

subset of array in golang

问题

我正在尝试用Python编写与以下代码行等效的代码:

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

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

class Object:
    def __init__(self, x):
        self.x = x

class Group:
    def __init__(self):
        self.objects = []

    def get(self):
        return [obj for obj in self.objects]

arr = Group()
arr.objects.append(Object(1))
print(arr.objects)
arr2 = arr.get()
arr.objects[0].x = 3
print(arr.objects)
print(arr2)

这段代码可以编译和运行,并给出以下结果:

[<__main__.Object object at 0x7f8e3e7e8a90>]
[<__main__.Object object at 0x7f8e3e7e8a90>]
[<__main__.Object object at 0x7f8e3e7e8a90>]

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

谢谢帮助!

英文:

I am trying to write the equivalent of the following line in python

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

Here is my example code. Basically I am just trying to use a getter function (G.get) to get a subset of G. So I think I want arr2 to be a new array but containing the same object.

package main

import &quot;fmt&quot;

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

Which compiles and runs and gives me

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

My question is "Why does arr2 not contain the same instance of an Object as arr?" I believe I understand make only instantiates a Group thing which means it includes one Object in it. But then the for loop shouldn't create a new Object should it?

Thanks for the help!

答案1

得分: 2

这段简单的代码片段展示了发生了什么:

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

playground 示例

语句 b := a 将变量 a 中的 Object 值复制到变量 b 中。现在有两个值的副本。更改其中一个不会影响另一个。

这与 Python 不同,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)  // 输出 1
arr2 := arr.get()
arr[0].x = 3
fmt.Println(arr[0].x)  // 输出 3
fmt.Println(arr2[0].x) // 输出 3

playground 示例

英文:

This simpler snippet of code shows what's going on:

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

The statement b := a copies the Object value in variable a to the variable b. There are now two copies of the value. Changing one does not change the other.

This is different from Python where assignment copies a reference to a value.

The loop in the question also copies the values:

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

The variable v is a copy the slice element from *G. A copy of v is appended to slice H. There are three independent Object values: the value in slice *G, the value in v and the value in slice H.

If you want the slices to all refer to the same Object value, then store pointers to Object values in the slice:

type Group []*Object

arr := make(Group, 1)
arr[0] = &amp;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

huangapple
  • 本文由 发表于 2015年1月25日 12:38:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/28133288.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定