为什么以下代码没有恐慌? 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)
}
答案 0 :(得分:5)
内置delete()
的使用会从地图中删除条目。它不会删除/取消分配与删除的键关联的值所指向的内存。
在Go中,你无法管理这样的内存,Go是一种垃圾收集语言,释放内存是垃圾收集器的职责和责任。
你的代码没有恐慌,因为你有一个指向Person
类型值的(有效)指针,只要你拥有它,那个人就不会变得无效(它的内存不会被释放)
当您将代码更改为people[0].Name
时,您正在使用不在地图中的键索引地图(因为您刚刚使用delete()
将其删除),因此{的结果{3}}将是地图值类型的index expression,nil
类型为*Person
。并且尝试引用Name
结构指针的nil
字段将导致运行时混乱。