登录
首页 >  Golang >  Go问答

指针接收器函数中使用 nil 是安全的吗?

来源:stackoverflow

时间:2024-03-25 19:09:35 437浏览 收藏

在 Go 中使用指针接收器函数时,接收器本身可能为 nil。然而,这不会导致 nil 指针取消引用错误,因为方法调用会自动重写为使用接收器的地址。只有当接收器本身为 nil 时,才会引发恐慌。

问题内容

将鼠标悬停在 t1.print() 上时,我的 ide 抱怨:

通话中接收者“t”可能为“nil”

更详细地说:

使用“nil”接收器的方法调用可能会导致“nil 指针取消引用”

但是在尝试了代码之后,我似乎无法得到 nil 指针取消引用错误 。我缺少什么?我怎样才能导致该错误?

type T []string

func (t *T) Print() {
    log.Print(t)
    log.Print(*t)
    log.Print(&t)
    log.Print(&(*t))
}

func main() {
    var t1 T
    t1.Print()
}

解决方案


您不会收到 nil 指针取消引用错误,因为该程序中没有 nil 指针。

var t1 t 初始化 t 类型的值,该值不是指针类型。由于print方法有一个指针接收器,因此方法调用t1.print()会自动重写为(&t1).print()

如果 x(的类型)的方法集包含 m 并且参数列表可以分配给 m 的参数列表,则方法调用 x.m() 有效。如果x是可寻址的并且&x的方法集包含m,则x.m()是(&x).m()的简写

https://golang.org/ref/spec#Calls

&t1 的类型为 *t,是指针类型,但指针不为 nil。乍一看可能会令人困惑,因为 t1 实际上是 nil(一个 nil 切片),但寻址 nil 切片是完全合法的:

type t []string

func main() {
    var t1 t

    fmt.println(t1 == nil)  // true (nil slice)
    fmt.println(&t1 == nil) // false (non-nil pointer to nil slice)
}

https://play.golang.org/p/i-I0PYsjLew

要引发恐慌,接收者本身必须为零(而不是指向某个零值):

type T []string

func (t *T) Print() {
    log.Print(t)
    log.Print(*t) // panic: runtime error: invalid memory address or nil pointer dereference
}

func main() {
    var t1 *T // nil pointer
    t1.Print()
}

https://play.golang.org/p/9whVZgeAGnI

请注意,恐慌发生在方法内部,而不是调用方法的地方。这与 java、c++、c# 等其他语言不同,其中方法调用构成指针取消引用。 go 中的情况并非如此。

本篇关于《指针接收器函数中使用 nil 是安全的吗?》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于Golang的相关知识,请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>