何时使用 os?

谁能解释一下 os.Exit()panic()之间的主要区别,以及它们在围棋练习中是如何使用的?

81896 次浏览

首先,os.Exit()可以用来正常地退出程序而不会出现错误,并且不会惊慌,所以这是一个关键的区别。另一个问题是,可以使用 recover捕获、忽略或记录某处的恐慌。

但如果我们说的是一个错误的退出代码,我们假设:

当出现严重错误时,可以使用 panic,这可能是程序员在投入生产之前就应该发现的错误。这就是它打印堆栈的原因。

使用 os.Exit(errorCode)或类似的东西,如果你想:

  1. 为了脚本的目的控制程序的退出代码。

  2. 希望对预期的错误(例如用户输入错误)有序退出。

所以基本上恐慌是为你准备的,一个糟糕的退出代码是为你的用户准备的。

首先,每当你有一个“如何在实践中使用它”的问题,一个好的方法开始是 搜索的 Go 源代码(或任何足够大的 Go 代码库,真的) ,和 包裹文件的答案。

现在,os.Exitpanic是完全不同的。当程序或其部分达到不可恢复状态时使用 panic

当调用 panic时,包括隐式地针对运行时错误(如索引一个切片出界或类型断言失败) ,它会立即停止当前函数的执行,并开始解除 goroutine 的堆栈,同时运行任何延迟的函数。如果该解除程序到达 goroutine 的堆栈顶部,程序就会死亡。

当您需要中止程序 马上,(不可能恢复或运行延迟清理语句)并返回错误代码(其他程序可以使用该代码报告发生的情况)时,可以使用 os.Exit。这在测试中很有用,因为您已经知道在这个测试失败之后,另一个测试也会失败,所以您最好现在就退出。当您的程序已经完成了它需要做的所有事情,现在只需要退出,也就是说,在打印了一条帮助消息之后,也可以使用这种方法。

大多数时候你不会使用 panic(你应该返回一个 error代替) ,你几乎不需要 os.Exit以外的一些情况下在测试和快速程序终止。

主要区别是:

  1. os.Exit跳过延迟函数的执行。
  2. 使用 os.Exit,您可以指定退出代码。
  3. panic正在终止,而 os.Exit没有。(似乎其他答案没有提到这一点。)

如果需要执行延迟函数,那么除了 panic之外别无选择。(另一方面,如果希望跳过延迟函数的执行,可以使用 os.Exit。)

如果非 void 函数是这样定义的:

  1. 这个函数包含很多分支
  2. 所有分支都以 returnpanic终止

然后你不能用 os.Exit代替 panic,否则编译器将拒绝编译程序,说“在函数结束时缺少返回值”。(Go 在这里非常笨,甚至 log.Panic也不会终止一个函数。)

在其他情况下:

  1. 当真正连接的事情发生时,使用 panic,例如编程逻辑错误。
  2. 当需要立即退出时,使用 os.Exit,并使用指定的退出代码。