登录
首页 >  Golang >  Go问答

如何正确处理取消引用 nil 指针?

来源:stackoverflow

时间:2024-03-25 11:57:36 424浏览 收藏

取消引用 nil 指针会导致程序崩溃。在 Go 中,解决此问题的常用方法是使用指针接收器。然而,值接收器在某些情况下也是有用的。本文探讨了使用值接收器安全处理 nil 指针的优雅解决方案。它展示了使用值接收器测试 nil 的无效方法,并提供了使用指针接收器和值接收器的可行解决方案。

问题内容

为了说明问题:

假设您有以下结构,其中包含用于打印内容的方法显示(值接收器):

type listnode struct {
    val  int
    next *listnode
}


func (l listnode) display() {
    for &l != nil {
        fmt.printf("%v ->", l.val)
        l = *l.next
    }
    fmt.println()
}

func main() {
    num1 := listnode{2, &listnode{4, &listnode{3, nil}}}

    num1.display()
}

上面的执行将在最后一个循环中出错,因为我尝试使用以下输出取消引用 nil:

2 ->4 ->3 ->panic: runtime error: invalid memory address or nil pointer dereference
[signal sigsegv: segmentation violation code=0x1 addr=0x0 pc=0x109ae6f]

但是,将函数更改为指针接收器,它会优雅地变为:

func (l *listnode) display() {
    for l != nil {
        fmt.printf("%v ->", l.val)
        l = l.next
    }
    fmt.println()
}

满意的输出:

2 ->4 ->3 ->

作为一个“新手”,我认为由于 display() 函数是只读的,所以最好使用值接收器编写该函数,但遇到了这个问题。是否有一个更优雅的解决方案以及我缺少的值接收器或在原始函数中取消引用的更好方法?


解决方案


像这样测试值接收者的地址来查看它是否为 nil 是没有意义的:

for &l != nil {

这里,l是一个有值的变量,并且它永远不能为nil。

如果你有一个指针接收器,这将做到这一点,并且即使 l 为零时也能工作:

func (l *listnode) display() {
   for trc:=l; trc!=nil; trc=trc.next {
        fmt.printf("%v ->", trc.val)
    }
}

如果你得到一个值接收者:

func (l listnode) display() {
   for trc:=&l; trc!=nil; trc=trc.next {
        fmt.printf("%v ->", trc.val)
    }
}

拥有值接收器的事实并不会改变拥有指针字段的事实。并且您不需要将它们的形式强制为接收者的形式(值/指针)。他们可以保留指针。无需(显式)取消引用。

func (l ListNode) display() {
    curNode := &l
    for curNode != nil {
        fmt.Printf("%v ->", curNode.Val)
        curNode = curNode.Next
    }
    fmt.Println()
}

理论要掌握,实操不能落!以上关于《如何正确处理取消引用 nil 指针?》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!

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