为了账号安全,请及时绑定邮箱和手机立即绑定

检查 nil 指针取消引用的正确方法是什么?

检查 nil 指针取消引用的正确方法是什么?

Go
月关宝盒 2023-08-14 16:25:03
为了说明这个问题:假设您有以下结构体,其中包含用于打印内容的方法 display (值接收器):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()函数是只读的,因此最好使用值接收器编写该函数,但遇到了这个问题。是否有一个更优雅的解决方案以及我缺少的值接收器或在原始函数中取消引用的更好方法?
查看完整描述

4 回答

?
炎炎设计

TA贡献1808条经验 获得超4个赞

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


 for &l != nil {

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


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


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)

    }

}


查看完整回答
反对 回复 2023-08-14
?
繁花不似锦

TA贡献1851条经验 获得超4个赞

以下是指针取消引用:


v = *ptr

如果 ptr 为零,这将崩溃。在取消引用之前检查是否为零。


if ptr != nil {

    v = *ptr

    // ...... 

}


查看完整回答
反对 回复 2023-08-14
?
蛊毒传说

TA贡献1895条经验 获得超3个赞

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


func (l ListNode) display() {

    curNode := &l

    for curNode != nil {

        fmt.Printf("%v ->", curNode.Val)

        curNode = curNode.Next

    }

    fmt.Println()

}


查看完整回答
反对 回复 2023-08-14
?
慕标琳琳

TA贡献1830条经验 获得超9个赞

某种递归解决方案


package main


import "fmt"


type ListNode struct {

    Val  int

    Next *ListNode

}


func (l *ListNode) display() {

    if l != nil {

        fmt.Printf("%v ->", l.Val)

        l.Next.display()

    }

    fmt.Println()

}


func main() {

    num1 := &ListNode{2, &ListNode{4, &ListNode{3, nil}}}


    num1.display()

}


查看完整回答
反对 回复 2023-08-14
  • 4 回答
  • 0 关注
  • 139 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信