为了账号安全,请及时绑定邮箱和手机立即绑定

在 Go 中使用递归引用

在 Go 中使用递归引用

Go
繁星coding 2021-07-03 07:15:26
我想在一个映射中包含我的所有命令,并从命令映射到一个执行工作的函数(只是一个标准的调度表)。我从以下代码开始:package mainimport "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提出了一种方法,我在下面给出了答案。它可以处理递归类型,还允许对所有命令的映射进行静态初始化。
查看完整描述

3 回答

?
江户川乱折腾

TA贡献1851条经验 获得超5个赞

您可能已经发现,Go 规范声明(我的重点):

如果 A 的初始化器依赖于 B,则 A 将设置在 B 之后。 依赖分析不依赖于被初始化项的实际值,只依赖于它们在源中的出现。如果 A 的值包含对 B 的提及、包含一个其初始值设定项提及 B 的值或递归提及提及 B 的函数,则 A 依赖于 B 。如果这种依赖形成一个循环,则是错误的。

所以,不,不可能做你想做的事。问题 1817提到了这个问题,Russ Cox 确实说 Go 中的方法有时可能会过度限制。但它很清楚且定义明确,并且可以使用变通方法。

因此,绕过它的方法仍然是使用init(). 对不起。


查看完整回答
反对 回复 2021-07-05
?
蝴蝶不菲

TA贡献1810条经验 获得超4个赞

只需在使用之前在函数内填充地图list()。像那样

Sry 我没有看到你写了“没有init()”:那是不可能的。



查看完整回答
反对 回复 2021-07-05
  • 3 回答
  • 0 关注
  • 272 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信