在 Go 中映射是通过值传递还是通过引用传递?

地图是否在 Go 中通过值或引用传递?

总是有可能定义一个函数如下,但这是一个过度杀伤?

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

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

这样做的目的当然是为了避免不必要的数据复制。

110602 次浏览

在这个帖子里,你会找到你的答案:

戈兰: 使用地图的引用访问地图

您不需要在映射中使用指针。

映射类型是引用类型,如指针或切片[1]

如果你需要改变会话,你可以使用一个指针:

map[string]*Session

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

不,地图是默认的参考。

    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
// hello => 1
// world => 2
// -----------------------
// hello => 3
// world => 4
// new_word => 5
// -----------------------


}

来自戈兰博客-

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

// Ex of make function
m = make(map[string]int)

代码段链接 使用它。

以下是戴夫 · 切尼(Dave Cheney)的 如果 map 不是引用变量,那么它是什么?中的一些片段:

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

结论:

结论

与通道不同,映射只是指向运行时的指针 如上所述,map 只是指向 runtime.hmap的指针 结构。

中的任何其他指针值具有相同的指针语义 没有魔法保存重写的地图语法由 编译器转换为对 runtime/hmap.go中函数的调用。

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

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

这是一个很好的问题,如果映射是指针值,为什么 表达式 make(map[int]int)返回一个类型为 它不是应该返回一个 *map[int]int吗? 伊恩・泰勒 这个问题最近在一个螺母线程 1中得到了回答。

早期我们称之为地图的东西被写成指针, 所以你写了 *map[int]int当我们意识到 没有人不写 *map就写 map

可以说,将类型从 *map[int]int重命名为 map[int]int,而 因为类型看起来不像一个指针,所以很容易混淆 比不能取消引用的指针形状的值更令人困惑。