subset of array in golang

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

subset of array in golang

问题

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

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

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

  1. class Object:
  2. def __init__(self, x):
  3. self.x = x
  4. class Group:
  5. def __init__(self):
  6. self.objects = []
  7. def get(self):
  8. return [obj for obj in self.objects]
  9. arr = Group()
  10. arr.objects.append(Object(1))
  11. print(arr.objects)
  12. arr2 = arr.get()
  13. arr.objects[0].x = 3
  14. print(arr.objects)
  15. print(arr2)

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

  1. [<__main__.Object object at 0x7f8e3e7e8a90>]
  2. [<__main__.Object object at 0x7f8e3e7e8a90>]
  3. [<__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.

  1. package main
  2. import &quot;fmt&quot;
  3. type Object struct {
  4. x int
  5. }
  6. type Group []Object
  7. func (G *Group) get() (H []Object) {
  8. for _,v := range *G {
  9. H = append(H,v)
  10. }
  11. return
  12. }
  13. func main() {
  14. arr := make(Group,1)
  15. arr[0].x = 1
  16. fmt.Println(arr)
  17. arr2 := arr.get()
  18. arr[0].x = 3
  19. fmt.Println(arr)
  20. fmt.Println(arr2)
  21. }

Which compiles and runs and gives me

  1. [{1}]
  2. [{3}]
  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

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

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

playground 示例

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

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

问题中的循环也复制了值:

  1. for _,v := range *G {
  2. H = append(H,v)
  3. }

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

如果你希望所有的切片都引用同一个 Object 值,那么在切片中存储指向 Object 值的指针:

  1. type Group []*Object
  2. arr := make(Group, 1)
  3. arr[0] = &Object{x: 1}
  4. fmt.Println(arr[0].x) // 输出 1
  5. arr2 := arr.get()
  6. arr[0].x = 3
  7. fmt.Println(arr[0].x) // 输出 3
  8. fmt.Println(arr2[0].x) // 输出 3

playground 示例

英文:

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

  1. var a Object
  2. a.x = 1
  3. b := a
  4. fmt.Println(a, b) // prints {1} {1}
  5. b.x = 2
  6. 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:

  1. for _,v := range *G {
  2. H = append(H,v)
  3. }

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:

  1. type Group []*Object
  2. arr := make(Group, 1)
  3. arr[0] = &amp;Object{x: 1}
  4. fmt.Println(arr[0].x) // prints 1
  5. arr2 := arr.get()
  6. arr[0].x = 3
  7. fmt.Println(arr[0].x) // prints 3
  8. 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:

确定