Go指针方法陷阱?2-3-4树实现代码差异解析
2-3-4树实现中的Go代码逻辑差异解析
我正在实现2-3-4树,节点结构定义如下:
type Node struct { items []int childs []*Node parent *Node }
我原本认为以下两段代码逻辑一致,但其中一段存在错误,现解析二者差异:
正确代码
cur = cur.parent cur._insertNode(upTo, rn) upTo, rn = cur._splitNode()
错误代码
cur.parent._insertNode(upTo, rn) upTo, rn = cur.parent._splitNode() cur = cur.parent
差异分析
这既不是Go指针方法陷阱,也不是编译器bug,核心问题在于代码执行顺序中cur.parent的指向可能在操作后发生变化:
正确代码的执行逻辑:
- 先将
cur指向其父节点,后续所有操作都基于这个固定的父节点引用 - 调用该父节点的
_insertNode方法 - 调用同一个父节点的
_splitNode方法,更新upTo和rn
- 先将
错误代码的执行逻辑:
- 先调用
cur.parent._insertNode,这一步操作可能会修改cur.parent的结构(比如分裂操作可能导致原父节点被替换,cur的parent指针指向新节点) - 接着调用
cur.parent._splitNode时,此时的cur.parent已经不是第一步调用时的那个父节点了 - 最后将
cur赋值为cur.parent,但此时的父节点已经是被修改后的,和预期的初始父节点完全不一致
- 先调用
简单来说,错误代码中两次访问cur.parent得到的可能是不同的节点,而正确代码通过提前将cur绑定到初始父节点,确保后续操作都基于同一个固定的节点引用,避免了中间操作导致父节点指针变化带来的逻辑错误。
内容的提问来源于stack exchange,提问作者Z.Sai
相关产品推荐
相关产品推荐

