删除指针值不会引发恐慌。

huangapple go评论85阅读模式
英文:

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)
}

Playground

英文:

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

答案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.

huangapple
  • 本文由 发表于 2017年8月15日 17:28:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/45690134.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定