2016-11-10 95 views
0

我在go.Now我有一個關於functoin通過variable.Here問題一個新的另一個FUNC變化圖是代碼:golang一個結構

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]} 

修改func我知道用戶是副本,所以更改名稱不工作是好的,但爲什麼更改地圖效果出用戶結構?

+0

任何理由使用'unsafe',而不是'fmt.Printf( 「%P \ N」,&U)'? – nothingmuch

+0

有趣的是,@nothingmuch實際上用這個用戶名回答他自己的問題! –

+2

因爲只有**地圖** **本身**按值傳遞(並且被複制):地圖的**內容**被地圖的所有副本共享。因此,地圖 - 正式被複制並通過值傳遞 - 就像它是一個引用類型一樣。 – Volker

回答

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) 
+0

thks,很好的答案 – user3819305

0

切片,地圖和頻道是參考類型。所以他們總是被引用傳遞。

+0

謝謝!我知道了 – user3819305