Golang中向列表追加元素时遇到的错误

Golang中向列表追加元素时遇到的错误 我是一名从C/C++转来的Go语言新手,在这行代码上一直遇到段错误:

	name := names.Front().Next().Next()
	link := links.Front().Next().Next()
	image := images.Front()
	service := services.Front()

	var artist Artist

	// TODO: Fix nil Pointer access
	for i := 0; i < names.Len(); i++ {
		// fmt.Printf("Artist[%d]:\n\tName: %s\n\tLink: %s\n\tIcon: %s\n\tService: %s\n\t", i, name.Value, link.Value, image.Value, service.Value)

		artist = Artist{
			Name:       fmt.Sprint(name.Value),
			ArtistLink: fmt.Sprint(link.Value),
			Service:    fmt.Sprint(service.Value),
			ImageLink:  fmt.Sprint(image.Value),
		}
		artists.PushBack(artist)

		name.Next()
		link.Next()
		image.Next()
		service.Next()
	}

错误信息: panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x847948]

goroutine 1 [running]: main.main()

这段代码有什么问题?我已经用调试器检查过,这些变量都不是nil。问题是出在我向列表添加元素的方式上,还是出在我初始化变量的方式上?我实在想不明白。


更多关于Golang中向列表追加元素时遇到的错误的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

你能分享我们可以运行并复现错误的代码吗?

目前你发布的错误片段和代码片段之间没有关联。我们甚至不知道这究竟是 main 函数的一部分还是其他内容。

你使用了一些我们不知道其值的名称,我们也不清楚完整的错误信息可能指向哪一行代码……

更多关于Golang中向列表追加元素时遇到的错误的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


一个不需要下载额外依赖的最小化示例相当常见。

在准备过程中,您可能已经意识到问题与访问第136行中 serviceValue 有关(正如原始错误信息中提到的)。

进一步深入分析,您可能已经了解到 service 确实是 nil,因为 services.Front() 返回了 nil,这是由于 services 的长度为0。

至于为什么会这样,您需要自行检查您的HTML抓取代码。我今天没有心情去冒险违反某些服务条款。

问题出在循环中对链表节点的遍历逻辑上。当 namelinkimageservice 节点为 nil 时,调用 .Next() 或访问 .Value 会导致空指针解引用。

以下是修复后的代码示例:

name := names.Front()
link := links.Front()
image := images.Front()
service := services.Front()

var artist Artist

for i := 0; i < names.Len(); i++ {
    // 检查节点是否为 nil
    if name == nil || link == nil || image == nil || service == nil {
        break
    }

    artist = Artist{
        Name:       fmt.Sprint(name.Value),
        ArtistLink: fmt.Sprint(link.Value),
        Service:    fmt.Sprint(service.Value),
        ImageLink:  fmt.Sprint(image.Value),
    }
    artists.PushBack(artist)

    // 移动到下一个节点,可能为 nil
    name = name.Next()
    link = link.Next()
    image = image.Next()
    service = service.Next()
}

关键修改:

  1. 将初始节点设置为 Front(),而不是跳过前两个节点(除非这是你的明确意图)。
  2. 在循环内部添加了 nil 检查,防止访问 nil 节点的字段。
  3. Next() 的返回值重新赋给变量,以正确推进到下一个节点。

如果你的链表长度不一致,或者你确实需要跳过前两个节点,请确保在每次调用 Next() 后检查节点是否为 nil。例如:

name := names.Front()
if name != nil {
    name = name.Next()
}
if name != nil {
    name = name.Next()
}
// 对其他变量执行类似操作...

这样修改后,你的代码将不会因为空指针解引用而崩溃。

回到顶部