Go标准库container/list提供双向链表,适用于队列(FIFO)和栈(LIFO),但无泛型约束、不支持索引访问,所有操作基于*list.Element;Element含Value(interface{})及前后指针,增删查需通过Element进行,遍历用Next()/Prev(),删除前须先获取对应Element。

Go 标准库的 container/list 提供双向链表实现,适合构建队列(FIFO)和栈(LIFO),但需注意它不提供泛型约束、不支持索引访问,且操作基于 *list.Element,不是直接操作值。
理解 list.Element 是关键
container/list 的核心是 *list.Element,每个元素包含 Value 字段(类型为 interface{})以及前后指针。所有增删查操作都围绕 Element 展开,而非原始数据:
- 插入(如
PushFront)返回新生成的*list.Element,可缓存用于后续定位 - 遍历时需用
Next()/Prev()沿指针移动,不能用下标 - 删除某值前,必须先通过遍历或已有引用拿到对应 Element,再调用
Remove
用 list 实现队列(FIFO)
队列只需在尾部入队、头部出队,PushBack + Front + Remove 组合即可:
// 初始化
q := list.New()
// 入队(尾插)
q.PushBack("a")
q.PushBack("b")
// 出队(头取+删)
if q.Len() > 0 {
front := q.Front()
value := front.Value.(string) // 类型断言(注意安全)
q.Remove(front)
fmt.Println("dequeue:", value) // "a"
}
⚠️ 注意:每次出队都要检查 Len() > 0,否则 Front() 返回 nil,解引用 panic。
立即学习“go语言免费学习笔记(深入)”;
用 list 实现栈(LIFO)
栈只需在头部统一进出,用 PushFront 和 Front+Remove 即可:
s := list.New()
// 入栈
s.PushFront(10)
s.PushFront(20)
// 出栈
if s.Len() > 0 {
top := s.Front()
value := top.Value.(int)
s.Remove(top)
fmt.Println("pop:", value) // 20
}
也可统一用 PushBack + Back + Remove,逻辑对称,按习惯选一边保持一致即可。
类型安全与实用建议
- 避免裸用
interface{}:封装成泛型结构体(Go 1.18+)更安全,例如type Queue[T any] struct { l *list.List },内部封装类型转换 - 不依赖顺序索引:若需随机访问或按位置删改,
list不合适,考虑切片或自定义结构 - 遍历推荐 for-range 模式:
for e := q.Front(); e != nil; e = e.Next() { fmt.Println(e.Value) } - 清空链表:循环
Remove(Front())或直接q.Init()(重置为空链表,不释放内存)









