我最近看了一个视频,Ian Lance Taylor在视频中介绍了Go中新的泛型实现。
作为一个例子,他展示了一个像这样的二进制树的简单实现
type Node[T any] struct {
left, right *Node[T]
data T
}
type bTree[T any] struct {
root *Node[T]
compare func(T, T) int
}
以及像这样的二叉树的搜索方法的实现
func (bt *bTree[T]) findDoublePointer(v T) **Node[T] {
pl := &bt.root
for *pl != nil {
switch cmpRes := bt.compare(v, (*pl).data); {
case cmpRes < 0:
pl = &(*pl).left
case cmpRes > 0:
pl = &(*pl).right
default:
return pl
}
}
return pl
}
我调用的findDoublePointer
方法返回一个指向树的Node
的指针。
我的问题是,这是否只是一个解释其他东西的例子,在这种情况下是泛型的想法,或者在这种情况中是否有充分的理由返回指针到指针。
我问这个问题的原因是,在我看来,用这样的代码可以实现查找方法的更简单版本
func (bt *bTree[T]) findPointer(v T) *Node[T] {
pl := bt.root
for pl != nil {
switch cmpRes := bt.compare(v, (*pl).data); {
case cmpRes < 0:
pl = (*pl).left
case cmpRes > 0:
pl = (*pl).right
default:
return pl
}
}
return pl
}
findDoublePointer
返回一个指向与值v
最匹配的子树的指针。它与泛型无关,如果缺少值,它是查找insert的好方法。
如果双指针指向非nil子树,则表示该树包含等于v
的值。但如果它指向nil
,那么它正是添加以v
为值的新Node
的地方。
func main() {
t := NewIntTree(0)
pt := &t
p1 := pt.findDoublePointer(1)
// *p1 == nil
// Insert `1` into the tree
*p1 = NewNode[int](1)
p1 = pt.findDoublePointer(1)
// Success: 1 is in the tree
println("1 node: ", *p1, (*p1).data)
}
完整示例:https://go.dev/play/p/X80joH39G5C