Oma*_*yam 0 function parameter-passing go mutability
在第一种情况下,我按值传递一个映射: package main
import (
"fmt"
"time"
)
func timeMap(z map[string]interface{}) {
z["updated_at"] = time.Now()
}
func main() {
foo := map[string]interface{}{
"Matt": 42,
}
timeMap(foo)
fmt.Println(foo)
}
Run Code Online (Sandbox Code Playgroud)
输出是一个静音地图:
map[updated_at:2009-11-10 23:00:00 +0000 UTC Matt:42]
Run Code Online (Sandbox Code Playgroud)
在第二种情况下,代码几乎相同,但通过引用传递:
package main
import (
"fmt"
"time"
)
func timeMap(z *map[string]interface{}) {
(*z)["updated_at"] = time.Now()
}
func main() {
foo := map[string]interface{}{
"Matt": 42,
}
timeMap(&foo)
fmt.Println(foo)
}
Run Code Online (Sandbox Code Playgroud)
显然,结果不同:
map[Matt:42 updated_at:2009-11-10 23:00:00 +0000 UTC]
Run Code Online (Sandbox Code Playgroud)
我的期望如下:
为什么会出现这样的情况呢?
Go 中不存在引用传递之类的东西。每当你传递任何东西(指针、切片头、映射)时,它总是按值传递。问题是到底什么是按值传递的(即value类型的实际值是什么)。
当你传递一个映射时,你传递了一个指向其头部的指针的副本,其中包含一组指向存储桶的指针,就像在哈希表的实现中一样。https://github.com/golang/go/blob/master/src/runtime/hashmap.go#L106
因此,将指针传递给映射几乎没有意义,因为复制映射头指针的操作非常便宜。
现在为什么顺序不同,这仅仅是由于映射的内部实现,键的范围以随机方式发生。同样,这只是一个实现细节。
编辑:
正如 @icza 正确指出的那样,传递映射实际上是将指针的副本传递给映射头,而不是映射头本身。对困惑感到抱歉
| 归档时间: |
|
| 查看次数: |
1415 次 |
| 最近记录: |