Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Recursion Golang结构上的递归函数_Recursion_Go - Fatal编程技术网

Recursion Golang结构上的递归函数

Recursion Golang结构上的递归函数,recursion,go,Recursion,Go,我有以下代码将*小部件结构组织到一个层次结构中Parent()返回带有调用方parentID ID的小部件。层次结构的深度可以达到4或5级 type Widget struct { ID int64 ParentID int64 } func (w *Widget) Parent() *Widget { // Returns the widget with an ID of w.ParentID } 我想要实现的是一个函数,它将父对象以及父对象的父对象等聚合到层次结构的顶部,并返

我有以下代码将
*小部件
结构组织到一个层次结构中
Parent()
返回带有调用方parentID ID的小部件。层次结构的深度可以达到4或5级

type Widget struct {
  ID int64
  ParentID int64
}

func (w *Widget) Parent() *Widget {
  // Returns the widget with an ID of w.ParentID
}
我想要实现的是一个函数,它将父对象以及父对象的父对象等聚合到层次结构的顶部,并返回所有父对象ID的一部分。由于我不知道层次结构的深度,我认为我需要某种编程递归来获取每个父级的父级,这将执行如下操作:

func (w *Widget) AllParents() []*Widget {
  var parentWidgets []*Widget
  x := w.Parent()
  parentWidgets = append(parentWidgets, x)
  y := x.Parent()
  parentWidgets = append(parentWidgets, y)
  ...
  return parentWidgets
}

有没有更惯用的方法来实现这一点?

您只需要在层次结构中越走越高,直到找到根为止。假设
Widget.Parent()
返回
nil
,如果
Widget
是“根”(意味着它没有父对象):

迭代解 下面是一个简单的
for
循环的解决方案:

func (w *Widget) AllParents() []*Widget {
    var ws []*Widget
    for parent := w.Parent(); parent != nil; parent = parent.Parent() {
        ws = append(ws, parent)
    }
    return ws
}
如果在“根”(对于所有切片类型)上调用,此方法将返回
nil
。在其他情况下,它将返回从直接父级到“根”的“路径”

这里有一个小测试程序。它创建一个ID为0的根小部件、ID为1的子部件和ID为2的“孙子”小部件,并打印每个小部件调用的
AllParents()
。为了实现Widget.Parent(),我使用了一个简单的“Widget注册表”映射

结果如预期:

Parents of 0:
Parents of 1: 0
Parents of 2: 1 0
试穿一下

递归解 当然,也可以使用递归来解决:

func (w *Widget) AllParents() []*Widget {
    if parent := w.Parent(); parent == nil {
        return nil
    } else {
        return append(parent.AllParents(), parent)
    }
}
此解决方案返回从根到直接父的“路径”

使用此实现运行上述测试程序,输出为:

Parents of 0:
Parents of 1: 0
Parents of 2: 0 1
试穿这个

Parents of 0:
Parents of 1: 0
Parents of 2: 0 1