英文:
Deleting pointer value doesn't panic
问题
为什么以下代码不会引发 panic?test
明确是一个指针。如果使用 fmt.Println(people[0].Name)
而不是 fmt.Println(test.Name)
,它会引发 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)
}
英文:
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)
}
答案1
得分: 5
使用内置的delete()
函数可以从映射中删除一个条目。它不会删除/释放与被删除键关联的值所指向的内存。
在Go语言中,你不能像这样管理内存,Go是一种垃圾回收语言,释放内存是垃圾回收器的职责和责任。
你的代码不会引发恐慌,因为你有一个(有效的)指向Person
类型值的指针,只要你拥有它,该人就不会变得无效(其内存不会被释放)。
当你将代码更改为people[0].Name
时,你正在使用一个在映射中不存在的键进行索引(因为你刚刚用delete()
删除了它),所以索引表达式的结果将是映射值类型的零值,对于*Person
类型来说,它是nil
。而尝试引用nil
结构指针的Name
字段将导致运行时恐慌。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论