我什么时候应该在golang中使用panic vs log.fatalln()?

end*_*and 40 go

log.Fatalln()上的文档:

func Fatalln(v ... interface {})Fatalln等同于Println(),然后调用os.Exit(1).

Fatalln 的源代码:

   310  // Fatalln is equivalent to Println() followed by a call to os.Exit(1).
   311  func Fatalln(v ...interface{}) {
   312      std.Output(2, fmt.Sprintln(v...))
   313      os.Exit(1)
   314  }
Run Code Online (Sandbox Code Playgroud)

似乎主要区别在于错误是否可以恢复(因为你可以恢复恐慌) - 这些之间有什么更明显的不同吗?

Panic的接口定义是:

   215  // The panic built-in function stops normal execution of the current
   216  // goroutine. When a function F calls panic, normal execution of F stops
   217  // immediately. Any functions whose execution was deferred by F are run in
   218  // the usual way, and then F returns to its caller. To the caller G, the
   219  // invocation of F then behaves like a call to panic, terminating G's
   220  // execution and running any deferred functions. This continues until all
   221  // functions in the executing goroutine have stopped, in reverse order. At
   222  // that point, the program is terminated and the error condition is reported,
   223  // including the value of the argument to panic. This termination sequence
   224  // is called panicking and can be controlled by the built-in function
   225  // recover.
   226  func panic(v interface{})
Run Code Online (Sandbox Code Playgroud)

看来恐慌不会返回任何东西.

这是主要的区别吗?否则,它们似乎在应用程序中执行相同的功能,假设没有恢复恐慌.

Jim*_*imB 40

  • 日志消息转到配置的日志输出,而恐慌只会写入stderr.

  • Panic将打印堆栈跟踪,这可能与错误无关.

  • 当程序发生混乱时会执行os.Exit延迟,但会立即调用退出,并且无法运行延迟函数.

通常,仅panic用于编程错误,其中堆栈跟踪对于错误的上下文很重要.如果消息不是针对程序员,那么您只是将消息隐藏在多余的数据中.

  • “致命”不执行延期的事实是IMO的一个大问题,我看不到这如何使其成为可行的解决方案。例如,由于这个原因,我的程序无法清理其临时目录… (3认同)
  • 如果处理临时目录的函数返回错误,则 defer 将被调用,调用者有责任决定是否需要 `log.Fatal`。也许? (2认同)

mro*_*man 8

panic通常用于小程序中,一旦出现错误,您不知道如何处理或不想处理,就终止程序。的缺点panic正是:它会终止程序(大多数情况下,除非您使用recover)。它通常不好使用,panic除非您打算从中恢复,或者除非发生了某些事情您根本无法恢复,否则您可以正常终止程序。例如,考虑一个为您提供功能的 API,但该 API 秘密地有一个panic地方,您注意到您的程序因此而在生产中终止。因此,您编写的任何代码的“外部 API”都应该从恐慌中恢复并返回错误。同样的事情适用于终止程序的任何事情。

但是, os.Exit() 无法从中恢复,也不执行 defers。