为什么一个功能中的映射值会受到另一个功能中的映射项的影响?

Here's my code:

func test(v map[string]string) {
    v["foo"] = "bar"
}

func main() {
    v := make(map[string]string)
    test(v)
    fmt.Printf("%v
", v) // prints map[foo:bar]
}

I'm pretty new to Go, but as far as I was aware, since I'm passing the map value to test() and not a pointer to the map, the test() function should modify a different variable of the map, and thus, not affect the value of the variable in main(). I would have expected it to print map[]. I tested a different scenario:

type myStruct struct {
    foo int
}

func test2(v myStruct) {
    v.foo = 5
}

func main() {
    v := myStruct{1}
    test2(v)
    fmt.Printf("%v
", v) // prints {1}
}

In this scenario, the code behaves as I would expect. The v variable in the main() function is not affected by the changes to the variable in test2(). So why is map different?

You are right in that when you pass something to a function, a copy will be made. But maps are some kind of descriptors to an underlying data structure. So when you pass a map value to a function, only the descriptor will be copied which will denote / point to the same data structures where the map data (entries) are stored.

This means if the function does any modification to the entries of the map (add, delete, modify entries), that is observed from the caller.

Read The Go Blog: Go maps in action for details.

Note that the same applies to slices and channels too; generally speaking the types that you can create using the built-in make() function. That's why the zero value of these types is nil, because a value of these types need some extra initialization which is done when calling make().

In your other example you are using a struct value, they are not descriptors. When you pass a struct value to another function, that creates a complete copy of the struct value (copying values of all its fields), which –when modified inside the function– will not have any effect on the original, as the memory of the copy will be modified – which is distinct.