golang另一个func更改结构的地图

时间:2016-11-10 04:43:27

标签: go

我是一个新的人。现在我对functoin传递变量有疑问。这是代码:

type User struct {
    Name string
    Map  map[string]string
}
func main() {
    u := User{Name: "Leto"}
    u.Map = make(map[string]string)
    fmt.Println("before --------")
    fmt.Println(unsafe.Pointer(&u))
    fmt.Println(unsafe.Pointer(&(u.Map)))
    fmt.Println(u)
    Modify(u)
    fmt.Println("after --------")
    fmt.Println(u)
}
func Modify(u User) {
    fmt.Println("in func --------")
    fmt.Println(unsafe.Pointer(&u))
    fmt.Println(unsafe.Pointer(&(u.Map)))
    u.Name = "Paul"
    u.Map["t"] = "t"
}
输出上面的

代码:

before --------
0xc04203a4c0
0xc04203a4d0
{Leto map[]}
in func --------
0xc04203a500
0xc04203a510
after --------
{Leto map[t:t]}

在修改功能我知道用户是副本,所以更改名称不起作用,但为什么要更改地图效果用户结构?

3 个答案:

答案 0 :(得分:0)

您应该在分配和修改操作中分别使用& User和* User。

选中此https://play.golang.org/p/tDh1JBpK-t

使用指向结构的指针总是更好。

答案 1 :(得分:0)

我们需要了解每次调用中内存分配的工作方式:

  u := User{Name: "Leto"}
// u is an object of type User
// after this line memory has been allocated to both the
// properties u.Name(string) and u.Map(reference)
// lets say allocated memory address for u.Name starts with x
// for u.Map it starts with y, and note that u.Map is a reference i.e. 
// the value contained in it will be a different memory address which
// will be the starting memory address of the actual map
// right now the value written at y is nil since it 
// does not point to any memory address
u.Map = make(map[string]string)
// now value of y has been updated to z (which is the 
// memory address of the beginning of the map initialized 
// with make call) 
fmt.Println("before --------")
fmt.Println(unsafe.Pointer(&u))
fmt.Println(unsafe.Pointer(&(u.Map)))
fmt.Println(u)
// here you are about to pass object by value 
// so basically a new object will be created of type User
// lets talk about how copy of this object will be created
// copy of u.Name will have a new address 
// lets call it x1 and the value "Leto" too will be 
// copied to memory address starting with x1
// copy of u.Map will have a new address too lets call it 
// y1 and its value z will be copied too to the memory address y1
// I think you must have got your answer by now. 
// Basically the newly copied object's property u.Map and 
// the old one's u.Map both points to the same memory address "z" 
// and hence whosoever updates the map the other one will see it
Modify(u)
fmt.Println("after --------")
fmt.Println(u)

答案 2 :(得分:-1)

切片,贴图和通道是参考类型。所以他们总是通过参考传递。