【问题标题】:For a struct vertex, what's the difference between map[int]vertex and map[int]*vertex?对于结构顶点,map[int]vertex 和 map[int]*vertex 有什么区别?
【发布时间】:2010-06-21 10:47:09
【问题描述】:

要定义从 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 // 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)
}

输出:

0 0 4 4
0 0 3 3
0 0 2 2

从输出中,我的理解是,如果我想原地改变结构成员,我必须使用指向结构的指针。 但我仍然不确定根本原因。特别是,为什么我不能分配给 a[0].x?

【问题讨论】:

    标签: go


    【解决方案1】:

    主要区别在于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
    

    b 中存储的顶点被v.x, v.y = 4, 4 行修改,而a 中存储的顶点没有。

    【讨论】:

    • map[int]vertex 存储一个值,map[int]*vertex 存储映射元素的指针。在 Go 中,切片、地图和通道是引用类型。
    • 对,我想我的措辞可能不清楚。我会对其进行编辑,希望它能表达我的意思。
    【解决方案2】:

    这个问题的答案很可能取决于 Go 地图是如何实现的。对于当前的实现,我会看一下 Go map 运行时标头 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
    

    【讨论】:

      猜你喜欢
      • 2010-11-18
      • 1970-01-01
      • 1970-01-01
      • 2014-08-29
      • 1970-01-01
      • 1970-01-01
      • 2016-12-24
      • 2023-03-04
      • 1970-01-01
      相关资源
      最近更新 更多