Go标准库container/list提供双向链表,适用于队列(FIFO)和栈(LIFO),但无泛型约束、不支持索引访问,所有操作基于*list.Element;Element含Value(interface{})及前后指针,增删查需通过Element进行,遍历用Next()/Prev(),删除前须先获取对应Element。
Go 标准库的 container/list 提供双向链表实现,适合构建队列(FIFO)和栈(LIFO),但需注意它不提供泛型约束、不支持索引访问,且操作基于 *list.Element,不是直接操作值。
container/list 的核心是 *list.Elem,每个元素包含
entValue 字段(类型为 interface{})以及前后指针。所有增删查操作都围绕 Element 展开,而非原始数据:
PushFront)返回新生成的 *list.Element,可缓存用于后续定位Next()/Prev() 沿指针移动,不能用下标Remove
队列只需在尾部入队、头部出队,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。
栈只需在头部统一进出,用 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 e := q.Front(); e != nil; e = e.Next() {
fmt.Println(e.Value)
}
Remove(Front()) 或直接 q.Init()(重置为空链表,不释放内存)