恐慌和断言之间有什么区别?

11
Go语言不提供断言(assertions)。它们无疑很方便,但我们的经验是程序员会将它们用作避免考虑适当的错误处理和报告的支撑。然而,它有print和println

panic像print一样,在打印后中止执行
panicln像println一样,在打印后中止执行

这难道不是一个断言吗?为什么他们声称上述内容但有panic呢?我可以看到它会导致相同的问题,但在其末尾添加了一个错误消息,这很容易被滥用。我错过了什么吗?

3
不,它不是。panic就像是“先写入再中止”,而断言则像是“测试,如果为假,则写入后中止”。无论如何,他们都无法阻止你执行类似断言的语句。 - zneak
1
zneak:很遗憾,你的评论不是一个答案:D - user34537
1
如果这个答案很好,我会把它转化为一个答案。 - zneak
4
说“程序员把它们当作拐杖使用”就像是在说我们程序员太蠢了,会用一个防盗警铃当门铃。 - Agnel Kurian
@Agnel 更糟糕的是,它完全无法理解程序逻辑错误和其他错误之间的区别,这些错误位于非常不同的空间。在编写正确的程序中,每个可能的非逻辑错误都会被预见、检查并报告。但当然不可能预见到每个可能的逻辑错误。此外,通过要求显式检查而不是提供异常,它们保证真正的程序将错过一些错误,并对每个检查施加了负担。不可靠的Unix技术没有检测到I/O错误也在这里重复出现。 - Jim Balter
3个回答

16
不,它不是。panic就像“先写再中止”,而assert则像“测试,如果为假,则先写再中止”。无论如何,他们都无法阻止你执行类似于assert的语句。

2
除了明显的,即panic不检查任何内容而assert检查,Go语言中您可以在发生panic时使用错误处理机制。
如果一个包认为发生了无法恢复的情况,它就会panic。
但是,包的用户,调用者(父级)可能希望检查或记录panic,然后继续panic,或者捕获它以正确处理该情况(例如,重试或使用其他包/函数)。
此外,assert-abort不会调用析构函数或任何其他东西。 但是,在Go中,即使发生panic,也将调用您defer的函数,因此一切都会被清理干净。
因此,正如您所看到的,与asserts相比,panic将允许各种清理任务。 这就是您提供的引言的含义。
有关defer、panic和recover的详细信息,请参见官方博客文章

1

首先,对于C语言来说,在assert()中仅在调试模式下才会终止程序的执行。


1
是的,这是一个非常错误的行为,也许正是谷歌想要防止的行为。为什么你希望在程序明显做错后还让它继续运行呢? - zneak
5
确切地说,如果预处理器中未定义 NDEBUG 宏,则会终止执行。但如果需要,仍然可以在非调试版本中使用 assert 。 - R Samuel Klatchko
3
首先,“Google”并不想在这里得到什么,只是一些碰巧在Google工作的人。其次,他们不能阻止任何事情——如果语言中没有断言,人们将简单地把它们从程序中删除掉。这不是希望你的程序在做错事后继续运行的问题——那是一个愚蠢的草人论证。相反,这是不希望为总是在正确程序中失败的检查付出成本的问题。断言是将错误的程序转变为正确程序的一种方式。 - Jim Balter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接