2017-08-15 74 views
0

爲什麼下面的代碼不會驚慌? test絕對是一個指針。與fmt.Println(people[0].Name)而不是fmt.Println(test.Name)它確實恐慌。刪除指針值不會恐慌

package main 

import "fmt" 

func main() { 

    type Person struct { 
     Id int 
     Name string 
    } 

    people := make(map[int]*Person) 

    people[1] = &Person{0, "Name"} 
    fmt.Println(people[0].Name) 

    test := people[0] 
    test.Name = "Name2" 
    fmt.Println(test.Name) 

    people[0].Name = "Name3" 
    fmt.Println(test.Name) 

    delete(people, 0) 

    fmt.Println(test.Name) 
} 

Playground

+0

問題中的代碼與操場中的代碼不同。你問哪一個? – Art

回答

5

使用內建delete()的刪除從地圖中的條目。它不會刪除/取消分配與刪除的鍵關聯的值所指向的內存。

在Go中你不能像這樣管理內存,Go是垃圾收集語言,釋放內存是垃圾收集器的責任和責任。

您的代碼不會因爲您有一個指向Person類型值的(有效)指針而發生恐慌,並且只要您擁有該指針,該人就不會失效(其內存不會被釋放)。

當你改變你的代碼people[0].Name,那麼你索引用鑰匙這是不是在地圖上(因爲你只是delete()刪除它)的地圖,所以index expression的結果將是價值的zero value地圖類型,nil*Person類型。並試圖參考nil結構指針的Name字段將導致運行時恐慌。