地图是通过价值或Go中的参考传递的吗?

时间:2016-11-18 15:42:06

标签: go

地图是通过Go?

中的值或引用传递的

总是可以将一个函数定义如下,但这是一种过度杀伤吗?

func foo(dat *map[string]interface{}) {...}

返回值的相同问题。我应该返回指向地图的指针,还是将地图作为值返回?

目的当然是避免不必要的数据复制。

3 个答案:

答案 0 :(得分:39)

在这个帖子中你会找到答案:

Golang: Accessing a map using its reference

  

您不需要使用带有地图的指针。

     

地图类型是引用类型,如指针或切片[1]

     

如果您需要更改会话,可以使用指针:

map[string]*Session
     

https://blog.golang.org/go-maps-in-action

答案 1 :(得分:7)

以下是戴夫·钱尼(Dave Chaney)的If a map isn’t a reference variable, what is it?中的一些内容:

  

映射值是指向runtime.hmap结构的指针。

和结论:

  

结论

     

地图与通道类似,但与切片不同,它们只是运行时的指针   类型。如上所示,映射只是指向运行时的指针。   结构。

     

映射与指针中的任何其他指针值具有相同的指针语义   去程序。除了通过   编译器调用runtime / hmap.go中的函数。

关于map语法的历史/解释的有趣一点:

  

如果地图是指针,那么它们不应该是* map [key] value吗?

     

这是一个很好的问题,如果地图是指针值,为什么   表达式make(map [int] int)返回一个类型为map [int] int的值。   它不应该返回* map [int] int吗?伊恩·泰勒(Ian Taylor)answered this recently in a golang-nuts线程1。

     

在早期,我们现在所说的地图被写为指针,   所以你写了* map [int] int。当我们意识到这一点时,我们就远离了   没有写过map的人没有写过*map

     

可以重命名   从* map [int] int到map [int] int的类型,但由于   类型看起来不像指针,比指针少混淆   形状值,无法取消引用。

答案 2 :(得分:0)

默认情况下,不引用任何地图。

    package main

    import "fmt"

    func mapToAnotherFunction(m map[string]int) {
        m["hello"] = 3
        m["world"] = 4
        m["new_word"] = 5
    }

    // func mapToAnotherFunctionAsRef(m *map[string]int) {
    // m["hello"] = 30
    // m["world"] = 40
    // m["2ndFunction"] = 5
    // }

    func main() {
        m := make(map[string]int)
        m["hello"] = 1
        m["world"] = 2

        // Initial State
        for key, val := range m {
            fmt.Println(key, "=>", val)
        }

        fmt.Println("-----------------------")

        mapToAnotherFunction(m)
        // After Passing to the function as a pointer
        for key, val := range m {
            fmt.Println(key, "=>", val)
        }

        // Try Un Commenting This Line
        fmt.Println("-----------------------")

        // mapToAnotherFunctionAsRef(&m)
        // // After Passing to the function as a pointer
        // for key, val := range m {
        //  fmt.Println(key, "=>", val)
        // }

        // Outputs
        // prog.go:12:4: invalid operation: m["hello"] (type *map[string]int does not support indexing)
        // prog.go:13:4: invalid operation: m["world"] (type *map[string]int does not support indexing)
        // prog.go:14:4: invalid operation: m["2ndFunction"] (type *map[string]int does not support indexing)

    }

来自Golang博客-

  

映射类型是引用类型,例如指针或切片,因此上面的m的值为nil;它没有指向初始化的地图。读取时,nil映射的行为类似于空映射,但是尝试写入nil映射将导致运行时恐慌。不要那样做要初始化地图,请使用内置的make函数:

m = make(map[string]int)

Code Snippet Link玩。