删除指针值不会死机

Why doesn't the following code panic? test is definitely a pointer. With fmt.Println(people[0].Name) instead of fmt.Println(test.Name) it does panic.

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

The use of the builtin delete() removes an entry from a map. It does not delete / deallocate the memory pointed by the value associated with the removed key.

In Go you can't manage memory like this, Go is a garbage collected language and freeing memory is the duty and responsibility of the garbage collector.

Your code doesn't panic because you have a (valid) pointer to a value of type Person, and as long as you have it, that person will not become invalid (its memory will not be freed).

When you change your code to people[0].Name, then you are indexing a map with a key which is not in the map (because you just removed it with delete()), so the result of the index expression will be the zero value of the value type of the map, which is nil for the *Person type. And attempting to refer to the Name field of a nil struct pointer will cause a runtime panic.