在 Go 中使用递归引用

我想在一个映射中包含我的所有命令,并从命令映射到一个执行工作的函数(只是一个标准的调度表)。我从以下代码开始:


package main


import "fmt"


func hello() {

    fmt.Print("Hello World!")

}


func list() {

    for key, _ := range whatever {

        fmt.Print(key)

    }

}


var whatever = map[string](func()) {

    "hello": hello,

    "list": list,

}

但是,它无法编译,因为函数和结构之间存在递归引用。尝试向前声明函数失败,并在定义时出现有关重新定义的错误,并且映射位于顶级。你如何定义这样的结构并在顶层初始化它们不必使用init()函数。

我在语言定义中没有看到好的解释。

  • 存在的前向引用用于“外部”函数,当我尝试前向声明函数时它不会编译。

  • 我也没有办法提前声明变量。

更新:我正在寻找一种解决方案,它不需要您在启动程序或init()函数时显式填充变量。不确定这是否可行,但它适用于我所知道的所有可比语言。

更新 2: FigmentEngine提出了一种方法,我在下面给出了答案。它可以处理递归类型,还允许对所有命令的映射进行静态初始化。


繁星coding
浏览 273回答 3
3回答

江户川乱折腾

您可能已经发现,Go 规范声明(我的重点):如果 A 的初始化器依赖于 B,则 A 将设置在 B 之后。 依赖分析不依赖于被初始化项的实际值,只依赖于它们在源中的出现。如果 A 的值包含对 B 的提及、包含一个其初始值设定项提及 B 的值或递归提及提及 B 的函数,则 A 依赖于 B 。如果这种依赖形成一个循环,则是错误的。所以,不,不可能做你想做的事。问题 1817提到了这个问题,Russ Cox 确实说 Go 中的方法有时可能会过度限制。但它很清楚且定义明确,并且可以使用变通方法。因此,绕过它的方法仍然是使用init(). 对不起。

蝴蝶不菲

只需在使用之前在函数内填充地图list()。像那样。Sry 我没有看到你写了“没有init()”:那是不可能的。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go