对于一个结构体 vertex,map[int]vertex 和 map[int]*vertex 有什么区别?

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

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

huangapple
  • 本文由 发表于 2010年6月20日 21:46:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/3079440.html
匿名

发表评论

匿名网友

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

确定