Dictionary 为什么一个函数中的映射值会受到另一个函数中映射项的影响?

Dictionary 为什么一个函数中的映射值会受到另一个函数中映射项的影响?,dictionary,go,struct,Dictionary,Go,Struct,这是我的密码: func test(v map[string]string) { v["foo"] = "bar" } func main() { v := make(map[string]string) test(v) fmt.Printf("%v\n", v) // prints map[foo:bar] } 我是个新手,但据我所知,因为我将map值传递给test,而不是指向map的指针,test函数应该修改map的另一个变量,因此不会影响main中变量的

这是我的密码:

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

func main() {
    v := make(map[string]string)
    test(v)
    fmt.Printf("%v\n", v) // prints map[foo:bar]
}
我是个新手,但据我所知,因为我将map值传递给test,而不是指向map的指针,test函数应该修改map的另一个变量,因此不会影响main中变量的值。我本以为它会打印地图[]。我测试了一个不同的场景:

type myStruct struct {
    foo int
}

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

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

在这个场景中,代码的行为与我预期的一样。主函数中的v变量不受test2中变量更改的影响。那么,为什么映射不同呢?

你说得对,当你将某个东西传递给函数时,就会生成一个副本。但映射是底层数据结构的某种描述符。因此,当您将映射值传递给函数时,只会复制描述符,该描述符将指示/指向存储映射数据项的相同数据结构

这意味着如果函数对映射的条目进行了任何修改,则添加、删除、修改条目,这是调用方观察到的

详情请阅读

注意,这同样适用于和;一般来说,可以使用内置函数创建的类型。这就是为什么这些类型的值为nil,因为这些类型的值需要一些额外的初始化,这是在调用make时完成的

在另一个示例中,您使用的是结构值,它们不是描述符。将结构值传递给另一个函数时,将创建结构值的完整副本,复制其所有字段的值,当在函数内部修改时,不会对原始值产生任何影响,因为副本的内存将被修改,这是不同的