本文详解 go 标准库 `container/list` 的正确用法,重点说明如何声明、传递和遍历双向链表,修正常见类型错误、语法错误及空指针误用,并提供可运行的加法链表实现示例。
在 Go 中,container/list 是标准库提供的双向链表实现,但其使用方式与许多其他语言(如 Python 或 Java)差异较大,初学者常因类型声明、值/指针传递、元素访问等细节出错。以下从核心要点出发,系统梳理关键实践。
"container/list" 是包路径,不是类型名;实际链表类型是 *list.List(通常以指针形式使用),而非 list 或 list.List 字面量。函数参数和返回值必须显式使用该类型:
func addTwoNumbers(l1 *list.List, l2 *list.List) *list.List {
// ...
}⚠️ 错误写法:func addTwoNumbers(l1 list, l2 list) —— list 不是有效类型,编译器会报 syntax error: unexpected name。
list.List 本身不支持下标或直接取值;所有数据访问必须通过 Element 对象完成:
因此,循环中应维护 e1, e2(指向当前元素),而非试图修改 l1 或 l2 本身(它们是容器,不可“移动”)。
以下代码已修复原问题中的全部错误:类型声明、变量作用域、元素访问、循环终止条件:
package main
import (
"container/list"
"fmt"
)
func main() {
// 构造输入链表(注意:题目中为逆序存储,如 (2→4→3) 表示数字 342)
l1 := list.New()
l1.PushBack(2) // 个位
l1.PushBack(4) // 十位
l1.PushBack(3) // 百位 → 表示 342
l2 := list.New()
l2.PushBack(5)
l2.PushBack(6)
l2.PushBack(4) // 表示 465
result := addTwoNumbers(l1, l2)
// 打印结果(同样为逆序)
for e := result.Front(); e != nil; e = e.Next() {
fmt.Print(e.Value, " ")
}
fmt.Println() // 输出:7 0 8 → 表示 807(342 + 465 = 807)
}
func addTwoNumbers(l1, l2 *list.List) *list.List {
carry := 0
result := list.New()
e1, e2 := l1.Front(), l2.Front()
for e1 != nil || e2 != nil || carry > 0 {
sum := carry
if e1 != nil {
sum += e1.Value.(int)
e1 = e1.Next()
}
if e2 != nil {
sum += e2.Value.(int)
e2 = e2.Next()
}
result.PushBack(sum % 10)
carry = sum / 10
}
return result
}掌握 container/list 的指针语义与元素抽象,是写出高效、安全 Go 链表逻辑的关键一步。对于简单场景,也可考虑切片([]int)替代——它更轻量、更符合 Go 的惯用风格。