英文:
For a struct vertex, what's the difference between map[int]vertex and map[int]*vertex?
问题
定义一个从int到struct vertex的映射,我应该定义map[int]vertex
还是map[int]*vertex
?哪个更好?
我扩展了Chickencha的代码:
package main
type vertex struct {
x, y int
}
func main() {
a := make(map[int]vertex)
b := make(map[int]*vertex)
v := &vertex{0, 0}
a[0] = *v
b[0] = v
v.x, v.y = 4, 4
println(a[0].x, a[0].y, b[0].x, b[0].y)
//a[0].x = 3 // 无法对(a[0]).x赋值
//a[0].y = 3 // 无法对(a[0]).y赋值
b[0].x = 3
b[0].y = 3
println(a[0].x, a[0].y, b[0].x, b[0].y)
u1 := a[0]
u1.x = 2
u1.y = 2
u2 := b[0]
u2.x = 2
u2.y = 2
println(a[0].x, a[0].y, b[0].x, b[0].y)
}
输出结果:
0 0 4 4
0 0 3 3
0 0 2 2
从输出结果来看,我的理解是,如果我想直接更改结构体成员,我必须使用指向结构体的指针。
但我仍然不确定其中的原因。特别是,为什么我不能对a[0].x赋值?
英文:
To define a map from int to struct vertex, should I define map[int]vertex
or map[int]*vertex
? Which one is preferred?
I extended Chickencha's code:
package main
type vertex struct {
x, y int
}
func main() {
a := make(map[int]vertex)
b := make(map[int]*vertex)
v := &vertex{0, 0}
a[0] = *v
b[0] = v
v.x, v.y = 4, 4
println(a[0].x, a[0].y, b[0].x, b[0].y)
//a[0].x = 3 // cannot assign to (a[0]).x
//a[0].y = 3 // cannot assign to (a[0]).y
b[0].x = 3
b[0].y = 3
println(a[0].x, a[0].y, b[0].x, b[0].y)
u1 := a[0]
u1.x = 2
u1.y = 2
u2 := b[0]
u2.x = 2
u2.y = 2
println(a[0].x, a[0].y, b[0].x, b[0].y)
}
The output:
0 0 4 4
0 0 3 3
0 0 2 2
From the output, my understanding is, if I want to change the struct member in place, I must use pointer to the struct.
But I'm still not sure the underlying reasons. Especially, why I cannot assign to a[0].x?
答案1
得分: 4
主要的区别是map[int]vertex
存储顶点的值,而map[int]*vertex
存储顶点的引用(指针)。以下程序的输出应该能够说明问题:
package main
type vertex struct {
x, y int
}
func main() {
a := make(map[int]vertex)
b := make(map[int]*vertex)
v := &vertex{0, 0}
a[0] = *v
b[0] = v
v.x, v.y = 4, 4
println(a[0].x, a[0].y, b[0].x, b[0].y)
}
输出结果:
0 0 4 4
在v.x, v.y = 4, 4
这一行中,存储在b中的顶点被修改了,而存储在a中的顶点没有被修改。
英文:
The main difference is that map[int]vertex
stores vertex values and map[int]*vertex
stores vertex references (pointers). The output of the following program should help illustrate:
package main
type vertex struct {
x, y int
}
func main() {
a := make(map[int]vertex)
b := make(map[int]*vertex)
v := &vertex{0, 0}
a[0] = *v
b[0] = v
v.x, v.y = 4, 4
println(a[0].x, a[0].y, b[0].x, b[0].y)
}
Output:
0 0 4 4
The vertex stored in b is modified by the v.x, v.y = 4, 4
line, while the vertex stored in a is not.
答案2
得分: 3
这个问题的答案可能取决于Go映射的实现方式。对于当前的实现,我建议查看Go映射的运行时头文件hashmap.h和代码文件hashmap.c。这还取决于你如何使用映射,例如对映射的活动类型和数量,键和元素数据结构等。
要原地更新向量元素的值,首先从映射中读取向量元素的值,然后更新元素的值,最后将更新后的元素值写入映射。例如:
package main
type vertex struct {
x, y int
}
func main() {
a := make(map[int]vertex)
a[0] = vertex{0, 0}
println(a[0].x, a[0].y)
v0 := a[0]
v0.x = 1
a[0] = v0
println(a[0].x, a[0].y)
}
输出结果:
0 0
1 0
英文:
The answer to this question is likely to be dependent on how Go maps are implemented. For the current implementation, I would take a look the Go map runtime header, hashmap.h, and code, hashmap.c, files. It's also going to depend on how you use the map e.g. what type and volume of activities against the map, key and element data structures, etc.
To update a vector element value in place, read the vector element value from the map, update the element value, write the updated element value to the map. For example
package main
type vertex struct {
x, y int
}
func main() {
a := make(map[int]vertex)
a[0] = vertex{0, 0}
println(a[0].x, a[0].y)
v0 := a[0]
v0.x = 1
a[0] = v0
println(a[0].x, a[0].y)
}
Output:
0 0
1 0
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论