3 回答
TA贡献1951条经验 获得超3个赞
您可能知道,Go 中的错误是返回值。由于 init() 不返回任何内容,如果出现任何问题,唯一的选择是在 init 中使用 panic()。
一个在 init 上发生恐慌的包可以说设计得不是很好,尽管可能有有效的用例。
鉴于这种情况,recover() 不是一个选项,因为 init 在 main 之前运行。所以如果你不能编辑有问题的包,那么你就不走运了。
这是为什么应该谨慎使用 panic 和 recovery 的原因之一,只有在字面上“恐慌”有意义的情况下。
@twotwotwo 提供了以下来自“ Effective Go”的引用,描述了这一点(对于 init 情况):
如果图书馆真的不能自行设置,那么恐慌可能是合理的,可以这么说
所以:如果您的 init 函数需要报告错误,那么问问自己该代码是否真的属于 init 或最好保存在其他地方。如果它真的必须是 init,请考虑在包内设置一个错误标志,并记录任何客户端必须检查该错误。
TA贡献1811条经验 获得超5个赞
是的,包init()
函数在函数之前main()
运行,请参阅语言规范中的包初始化。
不,您无法处理包init()
函数中发生的错误。即使可以,这也意味着您的程序所依赖的包无法初始化,并且您不知道会从中得到什么。
包init()
函数没有返回值,它们不能以一种有意义的方式来恢复。如果init()
函数发生恐慌,程序将终止。
由于init()
函数不是由您调用(例如从main()
函数调用),因此您无法从那里恢复。在初始化期间处理错误是包本身的责任,而不是包的用户。
在 期间发出错误信号的一种选择init()
是将错误状态存储在变量中(例如,导出的,或未导出的但可由导出的函数查询)。但这应该仅在合理继续时使用,这也是包本身的任务/责任(存储/报告错误),而不是包的用户。没有包的合作,你不能这样做(你不能“捕捉”未处理/未报告的错误和恐慌)。
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)
}
// ...
}
- 3 回答
- 0 关注
- 203 浏览
添加回答
举报