首页 文章

Map 是通过值传递还是通过引用传递给Go?

提问于
浏览
29

Go中的值是通过值传递还是引用?

始终可以将函数定义如下,但这是否过度?

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

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

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

3 回答

  • 29

    在这个主题中你会找到你的答案:

    Golang: Accessing a map using its reference

    您不需要使用带有 Map 的指针 . Map 类型是引用类型,如指针或切片[1]如果需要更改会话,可以使用指针:map [string] * Session
    https://blog.golang.org/go-maps-in-action

  • 0

    默认情况下,没有 Map 参考 .

    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博客 -

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

    m = make(map[string]int)

    Code Snippet Link玩它 .

  • 0

    以下是Dave Chaney发自If a map isn’t a reference variable, what is it?的部分内容:

    map值是指向runtime.hmap结构的指针 .

    和结论:

    结论 Map ,如通道,但不像切片,只是指向运行时类型的指针 . 如上所述,map只是指向runtime.hmap结构的指针 . 映射与Go程序中的任何其他指针值具有相同的指针语义 . 除了编译器将 Map 语法重写为运行时/ hmap.go中的函数调用之外,没有什么神奇之处 .

    关于 map 语法的历史/解释:

    如果 Map 是指针,它们不应该是* map [key]值吗?这是一个很好的问题,如果map是指针值,为什么表达式make(map [int] int)返回一个类型为map [int] int的值 . 它不应该返回* map [int] int吗? Ian Taylor最近在golang-nuts thread1中回答了这个问题 . 在早期我们称之为map的地方现在被写为指针,所以你写了* map [int] int . 当我们意识到没有人写过 Map 而没有写过 Map 时,我们就离开了 . 可以说,将类型从* map [int] int重命名为map [int] int,虽然因为类型看起来不像指针而混淆,但是比不能解除引用的指针形状值更容易混淆 .

相关问题