到目前为止,我一直避免使用log.Fatal
,但我最近偶然发现了这两个问题:code-coverage和tests-using-log-fatal.
100个代码覆盖问题中的一条 comments 说:
...在绝大多数情况下,
log.Fatal
应该仅在main或init函数中使用(或者可能在某些只能直接从它们调用的函数中使用)."
这让我开始思考,所以我开始查看Go提供的标准库代码.库中的test代码使用log.Fatal
的例子有很多,这看起来不错.在测试代码之外有几个示例,例如在net/http
中,如下所示:
// net/http/transport.go
func (t *Transport) putIdleConn(pconn *persistConn) bool {
...
for _, exist := range t.idleConn[key] {
if exist == pconn {
log.Fatalf("dup idle pconn %p in freelist", pconn)
}
}
...
}
如果避免使用log.Fatal
是最佳实践,那么为什么要在标准库中使用它,我应该只返回一个错误.调用os.Exit
而不为应用程序提供任何清理机会似乎对库的用户不公平.
我可能太天真了,所以我的问题似乎是更好的做法是拨打log.Panic
,这是可以回收的,而我理论上长期运行的稳定应用程序可能有机会起死回生.
那么,什么时候应该使用log.FATAL应该使用GO的最佳实践说明是什么呢?