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

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

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

Go
千巷猫影 2021-10-11 13:42:28
在 golang 中,当我导入一个模块时,它的 init() 被执行(在我假设的 main() 之前?),这个函数中可能会产生一些错误。如何捕获这些错误并在我自己的代码中处理它们?
查看完整描述

3 回答

?
饮歌长啸

TA贡献1951条经验 获得超3个赞

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

一个在 init 上发生恐慌的包可以说设计得不是很好,尽管可能有有效的用例。

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

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

@twotwotwo 提供了以下来自“ Effective Go”的引用,描述了这一点(对于 init 情况):

如果图书馆真的不能自行设置,那么恐慌可能是合理的,可以这么说

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


查看完整回答
反对 回复 2021-10-11
?
四季花海

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

是的,包init()函数在函数之前main()运行,请参阅语言规范中的包初始化。

不,您无法处理包init()函数中发生的错误。即使可以,这也意味着您的程序所依赖的包无法初始化,并且您不知道会从中得到什么。

init()函数没有返回值,它们不能以一种有意义的方式来恢复。如果init()函数发生恐慌,程序将终止。

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

在 期间发出错误信号的一种选择init()是将错误状态存储在变量中(例如,导出的,或未导出的但可由导出的函数查询)。但这应该仅在合理继续时使用,这也是包本身的任务/责任(存储/报告错误),而不是包的用户。没有包的合作,你不能这样做(你不能“捕捉”未处理/未报告的错误和恐慌)。


查看完整回答
反对 回复 2021-10-11
?
元芳怎么了

TA贡献1798条经验 获得超7个赞

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


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)

    }

    // ...

}


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

添加回答

举报

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