function - 传递值时与通过引用传递时 map 的奇怪突变(Golang)

标签 function go parameter-passing mutability

第一种情况中,我按值将 map 传递给: 包主

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

输出是一个静音贴图:

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

第二种情况中,代码几乎相同,但通过引用传递:

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

显然,结果不同:

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

我的期望如下:

  • 当通过值映射时静音
  • 当通过引用 map 时,就像在第二种 情况下一样被静音。 但是,在第一个 案例中, map 被静音但顺序相反(与第二个 案例相比)。

为什么会这样?

最佳答案

在 Go 中没有通过引用传递这样的东西。每当你传递任何东西(指针、 slice 头、映射)时,它总是按值传递。问题是究竟什么是按值传递的(即类型的实际 value 是什么)。

当你传递一个映射时,你将一个指针的副本传递给它的头部,它包含一组指向桶的指针,就像在哈希表的实现中一样。 https://github.com/golang/go/blob/master/src/runtime/hashmap.go#L106

因此,将指针传递给 map 几乎没有意义,因为复制 map header 指针的操作非常便宜。

现在为什么顺序不同,这仅仅是由于 map 的内部实现,键的范围以随机方式发生。同样,这只是一个实现细节。

编辑:

正如@icza 正确指出的那样,传递 map 实际上是将指针 的副本传递给 map header ,而不是 map header 本身。抱歉造成混淆

关于function - 传递值时与通过引用传递时 map 的奇怪突变(Golang),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44486749/

相关文章:

python-3.x - python : How do I alias a function with specific parameters?

c++ - 强制调用基类虚函数

mongodb - 使用 Golang 将日期插入 Mongodb

C将指针传递给函数混淆

Excel 搜索字符串

javascript - getElementById 类型错误 : "cannot set property ' innerHTML' of null

C# 将子列表用作基本列表

Java 函数传递和返回复杂数据类型

amazon-web-services - 如何从 AWS lambda 执行 exe 文件

rest - 如何在 golang 中使用 julienschmidt/httprouter 传递两个或多个参数?