next字段必须是指向结构体的指针而非结构体本身,因为go禁止结构体递归包含自身类型(否则内存大小无限),否则编译报错invalid recursive type node。

为什么 next 字段必须是指向结构体的指针,而不是结构体本身
Go 不允许结构体直接包含自身类型(会导致无限内存大小),所以链表节点的 next 字段只能是 *Node。写成 next Node 会编译报错:invalid recursive type Node。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 定义节点时,
next必须声明为指针类型:next *Node - 初始化新节点时,
next默认是nil,不用显式赋值 - 插入或遍历时,所有对
next的操作都基于指针解引用,比如current = current.next(current是*Node)
插入节点时常见的空指针 panic 场景
典型错误是没检查 head == nil 就直接访问 head.next,或者在循环中用 current.next.next 而没确认 current.next != nil。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 头插法前先判断
head == nil,否则新节点的next指向head即可 - 遍历找插入位置时,用
current != nil && current.next != nil控制循环条件 - 不要写
if current.next.data > x这类代码——必须先确保current.next != nil
append 和 insertAfter 在指针操作上的关键区别
两者看似都是“加节点”,但对指针的修改逻辑不同:append 改的是最后一个节点的 next 字段;insertAfter 改的是目标节点的 next,且要先保存原 next 值再重连。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
-
append:从head开始遍历到current.next == nil,然后current.next = newNode -
insertAfter:必须先newNode.next = target.next,再target.next = newNode;顺序反了会丢节点 - 如果
target是nil,insertAfter应该直接 panic 或返回错误,不静默失败
用 unsafe.Pointer 模拟“指针算术”是危险且不必要的
有人想模仿 C 风格的 node + offset 来跳转节点,但 Go 的 unsafe.Pointer 无法安全实现链表遍历,且破坏类型系统、绕过 GC 管理,极易引发崩溃或内存泄漏。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 老老实实用
node.next一级级移动,这是唯一安全、可读、可维护的方式 - 不要试图用
unsafe.Offsetof计算字段偏移来“优化”遍历——链表本就不是靠内存连续性提升性能的数据结构 - 如果真需要高性能随机访问,说明你该换用切片或 map,而不是硬改链表










