删除指针值不会引起恐慌

时间:2017-08-15 09:28:32

标签: pointers dictionary go

为什么以下代码没有恐慌? 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

1 个答案:

答案 0 :(得分:5)

内置delete()的使用会从地图中删除条目。它不会删除/取消分配与删除的键关联的值所指向的内存。

在Go中,你无法管理这样的内存,Go是一种垃圾收集语言,释放内存是垃圾收集器的职责和责任。

你的代码没有恐慌,因为你有一个指向Person类型值的(有效)指针,只要你拥有它,那个人就不会变得无效(它的内存不会被释放)

当您将代码更改为people[0].Name时,您正在使用不在地图中的键索引地图(因为您刚刚使用delete()将其删除),因此{的结果{3}}将是地图值类型的index expressionnil类型为*Person。并且尝试引用Name结构指针的nil字段将导致运行时混乱。