gpt4 book ai didi

go - Go 包是否应该使用 log.Fatal 以及何时使用?

转载 作者:IT老高 更新时间:2023-10-28 13:03:52 27 4
gpt4 key购买 nike

到目前为止,我一直避免使用 log.Fatal,但我最近偶然发现了这些问题; code-coveragetests-using-log-fatal .

100 个代码覆盖率问题中的一条评论说:

... In the vast majority of cases log.Fatal should be only be used in main, or init functions (or possibly some things meant to be called only directly from them)"

这让我思考,所以我开始查看 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 的最佳实践会说什么?

最佳答案

可能只有我一个人,但这里是我使用 log.Fatal 的方式。根据 UNIX 约定,遇到错误的进程应尽早失败,并使用非零退出代码。这引导我遵循以下准则,以便在……

时使用 log.Fatal
  1. ...在我的任何 func init() 中都会发生错误,因为这些错误分别发生在处理导入时或调用主 func 之前。相反,我只做不直接影响库或 cmd 应该做的工作单元的事情。例如,我设置了日志记录并检查我们是否有一个健全的环境和参数。如果我们有无效的标志,就不需要运行 main ,对吧?如果我们不能提供适当的反馈,我们应该尽早告知。
  2. …发生了一个我知道无法恢复的错误。假设我们有一个程序可以创建在命令行中给出的图像文件的缩略图。如果此文件不存在或由于权限不足而无法读取,则没有理由继续,并且此错误无法恢复。所以我们遵守约定并失败了。
  3. …在可能不可逆的过程中发生错误。这是一种软定义,我知道。让我来说明一下。假设我们有一个 cp 的实现,并且它开始是非交互的并且递归地复制一个目录。现在,假设我们在目标目录中遇到一个与要复制到那里的文件同名(但内容不同)的文件。由于我们不能要求用户决定要做什么,也不能复制这个文件,所以我们遇到了问题。因为当我们以退出代码 0 结束时,用户会假设源目录和目标目录是精确的副本,所以我们不能简单地跳过有问题的文件。但是,我们不能简单地覆盖它,因为这可能会破坏信息。这是我们无法从用户的显式请求中恢复的情况,因此我将使用 log.Fatal 来解释这种情况,从而遵循尽早失败的原则。<

关于go - Go 包是否应该使用 log.Fatal 以及何时使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33885235/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com