go中用指针实现链表是唯一自然方式,因其无引用类型且值默认拷贝传递,若next为node而非node,赋值会复制整个节点导致链表断裂;故next字段必须为node,操作也需用*node。
为什么用指针实现链表是 Go 的唯一自然方式
Go 没有引用类型(如 C++ 的 & 引用),也没有隐式地址传递;所有值默认按拷贝传递。若不用指针,Node 结构体每次传参或赋值都会复制整个节点(含数据和“下一个”字段),导致 next 指向的是副本而非原链上节点——链表直接断裂。所以 Go 中实现链表,next 字段必须是 *Node,操作节点也几乎总得用 *Node。
定义链表节点与基础操作的典型写法
一个最小可用的单向链表节点通常长这样:
type Node struct {
Data int
Next *Node
}
注意三点:
-
Next字段类型是*Node,不是Node;设为nil表示链尾 - 插入、删除、遍历等操作函数的接收者一般用
*Node或额外传入**Node(尤其涉及修改头节点时) - 不要在结构体里嵌入
*Node做“头指针”,应单独维护head *Node变量;否则易引发循环引用或误判空链表
插入节点时最容易踩的坑:忘记解引用或错用地址取值
比如在链表头部插入新节点,常见错误写法: