为了说明这个问题:
假设你有一个结构体,它有一个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条答案
按热度按时间56lgkhnf1#
测试值接收方的地址以查看它是否为空是没有意义的,如下所示:
这里,
l
是一个有值的变量,它永远不能为nil。如果你有一个指针接收器,这就可以了,即使
l
为nil也可以:如果您获得值接收器:
jaql4c8m2#
你有一个值接收器的事实并不会改变你有指针字段的事实。而且你不需要将它们的形式强制为接收器的形式(值/指针)。它们仍然可以是指针。不需要(显式地)解引用。
qmelpv7a3#
某种递归解法
yftpprvb4#
下面是一个指针取消引用:
如果ptr为nil,这将崩溃。在 * 取消引用之前检查nil *。