go踩过的坑–map作为入参

0.思考

当map作为函数入参的时候:

  1. 传递是是值还是指针?
  2. 函数里面对map进行修改,是否影响map的值?

1.map的定义

当用make函数定义一个map时,make返回了一个Type类型,看似好像返回了一个值,而非指针,其实不然。

m := make(map[int]int)
func make(t Type, size ...IntegerType) Type

源码里面对于map的make方法的具体实现如下(位于/src/runtime/hashmap.go):

func makemap_small() *hmap {
    h := new(hmap)
    h.hash0 = fastrand()
    return h
}

这里可以清楚的看到,map的make方法返回的是一个指针,该指针指向一个的结构体hmp。

2.map作为入参

既然map是通过指针进行传递的,那就可以在调用函数里面对map值进行修改。如下例子中,通过函数ChangeMap对map的值进行了修改。

package main

import "fmt"

func main(){
    m := make(map[int]int)
    m[1] = 1
    ChangeMap(m)
    fmt.Println(m)
}

//修改map
func ChangeMap(m map[int]int){
    m[1] = 0
}

执行结果为:

修改前: map[1:1]
修改后: map[1:0]

但是这个地方有个坑:如果把map修改为nil,则达不到修改map的目的。比如把ChangeMap函数改为

func ChangeMap(m map[int]int){
    m = nil
}

执行结果为:

修改前: map[1:1]
修改后: map[1:1]

可以发现,map值并没有修改成nil。

3.结论

  1. map作为函数入参是作为指针进行传递的
  2. 函数里面对map进行修改时,会同时修改源map的值,但是将map修改为nil时,则达不到预期效果。