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

时间:2016-03-14 20:02:25

标签: go

来自log.Fatalln()的文档:

  

func Fatalln(v ... interface {})Fatalln相当于Println()   然后调用os.Exit(1)。

Fatalln的source code

   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  }

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

恐慌的界面definition是:

   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{})

恐慌似乎没有任何回报。

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

2 个答案:

答案 0 :(得分:33)

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

  • 恐慌将打印堆栈跟踪,这可能与错误无关。

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

通常,只使用panic进行编程错误,其中堆栈跟踪对错误的上下文很重要。如果邮件不是针对程序员的,那么您只需将邮件隐藏在多余的数据中。

答案 1 :(得分:1)

panic通常用于小程序中,只要在出现错误而您不知道如何处理或不想处理时终止程序。 panic的缺点正是:它将终止程序(主要是,除非你使用recover)。使用panic通常不好,除非您打算从中恢复或除非发生了某些事情,否则您实际上无法恢复,也无法优雅地终止该程序。例如,考虑一个API,它为您提供功能,但API秘密地在某处panic,您会注意到您的程序因此而终止生产。因此,您编写的任何代码的“外向API”应该从恐慌中恢复并返回错误。同样的事情适用于终止程序的任何事情。

但是,os.Exit()无法恢复,也无法执行延迟。