如何在Golang中导入模块时捕获错误?

时间:2015-06-05 03:41:45

标签: import go

在golang中,当我导入一个模块时,它的init()被执行(在我假设的main()之前?),这个函数可能会产生一些错误。如何捕获这些错误并在我自己的代码中处理它们?

3 个答案:

答案 0 :(得分:4)

Go中的错误是返回值,您可能知道。由于init()不返回任何内容,唯一的选择是在init中出现panic(),如果出现任何问题。

在init上发生恐慌的软件包可能没有很好的设计,尽管可能存在有效的用例。

鉴于这种情况,recover()不是一个选项,因为init在main之前运行。所以如果你不能编辑有问题的包,那你就不走运了。

这是为什么应该谨慎使用恐慌和恢复的原因之一,只有在字面上“恐慌”才有意义的情况下。

@twotwotwo从“有效Go”中提供了以下引用,描述了这一点(对于init案例):

  

如果图书馆真的无法自我设定,恐慌可能是合理的,可以这么说

所以:如果您的init函数需要报告错误,那么问问自己该代码是否真的属于init,或者更好地保存在其他地方。如果它确实必须是init,请考虑在包内设置一个错误标志,并记录任何客户端必须检查该错误。

答案 1 :(得分:2)

是的,包init()函数在main()函数之前运行,请参阅语言规范中的Package initialization

不,您无法处理包init()函数中发生的错误。即使你可以,这也意味着你的程序所依赖的软件包无法初始化,你也不会知道该对它有什么期望。

init()个函数没有返回值,并且它们无法以有意义的方式从中恢复。如果init()函数发生混乱,程序将终止。

由于您未调用init()函数(例如来自main()函数),因此无法从那里恢复。包本身有责任在初始化期间处理错误,而不是包的用户。

init()期间发出错误信号的一个选项是将错误状态存储在变量中(例如,导出或未导出但可由导出的函数查询)。但是只有在合理的情况下才能使用它,这也是包本身(存储/报告错误)的任务/责任,而不是包的用户。如果没有包的合作,你就无法做到这一点(你可以"捕获"未处理/未报告的错误和恐慌)。

答案 2 :(得分:1)

不是直接的,但你可以使用这样的东西:

package mypkg

var InitErr error
var Foo MyFoo

func init() {
    Foo, InitErr = makeInitialisation()
    // ...
}

然后在你的主要:

package main

import "foo/bar/mypkg"

func main() {
    if (mypkg.InitErr != nil) {
        panic(err)
    }
    // ...
}