list - 检查 nil 指针取消引用的正确方法是什么?
问题描述
为了说明问题:
假设您有以下结构,其中包含用于打印内容的方法 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()
函数是只读的,因此最好使用值接收器编写该函数,但会遇到这个问题。是否有一个更优雅的解决方案与我缺少的值接收器或在原始函数中取消引用的更好方法?
解决方案
像这样测试值接收器的地址以查看它是否为 nil 是没有意义的:
for &l != nil {
这里,l
是一个有值的变量,它永远不能为零。
如果你得到一个指针接收器,这会做到,并且即使l
是 nil 也能工作:
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)
}
}
推荐阅读
- r - R function defined but not showing as object
- json - svelte - 从本地文件夹读取 json 文件
- laravel - Laravel: local.ERROR: Trying to get property 'body' of non-object
- python - How to access a dataclass docstring and comments
- java - Java 生态系统中是否有类似于 Rust 中的 cargo build 的替代方案?
- excel - 返回评估值满足 VBA 标准的范围内的最大值
- aws-lambda - 在 Azure 管道中安装 AWS lambda 工具时选择 nuget.org 作为源
- awk - 在文件中查找行并将其替换为另一个文件中的行
- sql - 每个部门的平均课程规模
- r - 根据R中的键重新编码多列