猿问

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

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


千巷猫影
浏览 204回答 3
3回答

饮歌长啸

您可能知道,Go 中的错误是返回值。由于 init() 不返回任何内容,如果出现任何问题,唯一的选择是在 init 中使用 panic()。一个在 init 上发生恐慌的包可以说设计得不是很好,尽管可能有有效的用例。鉴于这种情况,recover() 不是一个选项,因为 init 在 main 之前运行。所以如果你不能编辑有问题的包,那么你就不走运了。这是为什么应该谨慎使用 panic 和 recovery 的原因之一,只有在字面上“恐慌”有意义的情况下。@twotwotwo 提供了以下来自“ Effective Go”的引用,描述了这一点(对于 init 情况):如果图书馆真的不能自行设置,那么恐慌可能是合理的,可以这么说所以:如果您的 init 函数需要报告错误,那么问问自己该代码是否真的属于 init 或最好保存在其他地方。如果它真的必须是 init,请考虑在包内设置一个错误标志,并记录任何客户端必须检查该错误。

四季花海

是的,包init()函数在函数之前main()运行,请参阅语言规范中的包初始化。不,您无法处理包init()函数中发生的错误。即使可以,这也意味着您的程序所依赖的包无法初始化,并且您不知道会从中得到什么。包init()函数没有返回值,它们不能以一种有意义的方式来恢复。如果init()函数发生恐慌,程序将终止。由于init()函数不是由您调用(例如从main()函数调用),因此您无法从那里恢复。在初始化期间处理错误是包本身的责任,而不是包的用户。在 期间发出错误信号的一种选择init()是将错误状态存储在变量中(例如,导出的,或未导出的但可由导出的函数查询)。但这应该仅在合理继续时使用,这也是包本身的任务/责任(存储/报告错误),而不是包的用户。没有包的合作,你不能这样做(你不能“捕捉”未处理/未报告的错误和恐慌)。

元芳怎么了

不是直接的,但你可以使用这样的东西:package mypkgvar InitErr errorvar Foo MyFoofunc init() {    Foo, InitErr = makeInitialisation()    // ...}然后在您的主要内容中:package mainimport "foo/bar/mypkg"func main() {    if (mypkg.InitErr != nil) {        panic(err)    }    // ...}
随时随地看视频慕课网APP

相关分类

Go
我要回答