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()(重置为空链表,不释放内存)