dongmi5607 2017-06-11 17:34
浏览 29
已采纳

传递值与通过引用传递时映射的奇怪突变(Golang)

In the first case I pass a map to by value: 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)
}

The output is a muted map:

map[updated_at:2009-11-10 23:00:00 +0000 UTC Matt:42]

In the second case the code is almost identical but for passing by reference:

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)
}

Obviously, the result differs:

map[Matt:42 updated_at:2009-11-10 23:00:00 +0000 UTC]

My expectations were the following:

  • when passing by value map is not muted
  • When passing by reference map is muted like in the second case. However, in the first case map was muted but in the reverse order (compared to the second case).

Why does it happen so?

  • 写回答

1条回答 默认 最新

  • dsvcqvp139098 2017-06-11 17:45
    关注

    There is no such thing as passing by reference in Go. Whenever you pass anything (pointer, slice header, map) it is always passed by value. The question is what exactly is being passed by value (i.e. what is the actual value of the type).

    When u pass a map, you pass a copy of the pointer to its header, which contains a set pointers to the buckets, as in the implementation of the HashTable. https://github.com/golang/go/blob/master/src/runtime/hashmap.go#L106

    Therefore it rarely makes sense to pass a pointer to the map, because the operation of copying a map header pointer is extremely cheap.

    Now why the order is different, this is simply due to internal implementation of the map, ranging over the keys occurs in a random fashion. Again this is just an implementation details.

    EDIT:

    As @icza correctly pointed out, passing a map is actually passing a copy of a pointer to the map header, not the map header itself. Sorry for the confusion

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?