英文:
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 "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)
}
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}
语句 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
英文:
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}
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] = &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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论