示例 - 甚至是åˆå­¦è€…示例 - 是å¦åŒ…å«é”™è¯¯å¤„ç†ä»£ç ï¼Ÿ

时间:2009-04-11 13:54:02

标签: error-handling

在recent interview中,Brian Kernighan被问到了这个问题。我引用他的回å¤ï¼š

  布莱æ©ï¼šæˆ‘对此感到很伤心。错误处ç†ä»£ç å¾€å¾€ä½“积庞大,éžå¸¸æ— è¶£ä¸”没有破å性,因此它常常妨ç¢å­¦ä¹ å’Œç†è§£åŸºæœ¬è¯­è¨€ç»“构。åŒæ—¶ï¼Œé‡è¦çš„是æ醒程åºå‘˜é”™è¯¯ç¡®å®žå‘生,并且他们的代ç å¿…须能够应对错误。

     

我个人的å好是在教程的å‰é¢å‡ éƒ¨åˆ†ä¸­å¿½ç•¥é”™è¯¯å¤„ç†ï¼Œé™¤äº†æ到错误å¯èƒ½å‘生之外,类似于忽略å‚考手册中大多数示例中的错误,除éžæŸäº›éƒ¨åˆ†çš„内容是错误。但这å¯ä»¥å¼ºåŒ–æ— æ„识的信念,å³å¿½è§†é”™è¯¯æ˜¯å®‰å…¨çš„,这总是一个å主æ„。

我ç»å¸¸åœ¨è¿™é‡Œå’Œæˆ‘自己的åšå®¢ä¸Šç•™ä¸‹ä»£ç ç¤ºä¾‹ä¸­çš„错误处ç†ï¼Œæˆ‘注æ„到这是Stack Overflow的一般趋势。我们是在加强å习惯å—?我们是å¦åº”该花更多的时间æ¥å¤„ç†é”™è¯¯å¤„ç†çš„例å­ï¼Œæˆ–者它是å¦åªæ˜¯ä¸ºäº†è¯´æ˜Žè¿™ä¸€ç‚¹ï¼Ÿ

13 个答案:

答案 0 :(得分:11)

我认为这å¯èƒ½æ˜¯ä¸€ç§æ”¹è¿›ï¼Œå¦‚果在å‘布示例代ç æ—¶æˆ‘们至少会å‘表评论,说你应该在æŸäº›åœ°æ–¹æ”¾ç½®é”™è¯¯å¤„ç†ä»£ç ã€‚è¿™å¯èƒ½è‡³å°‘有助于使用该代ç çš„人记ä½ä»–们需è¦è¿›è¡Œé”™è¯¯å¤„ç†ã€‚这将ä¿ç•™ç”¨äºŽé”™è¯¯å¤„ç†çš„é¢å¤–代ç ï¼Œä½†ä»å°†å¼ºåŒ–需è¦é”™è¯¯å¤„ç†ä»£ç çš„想法。

答案 1 :(得分:6)

任何æ供的示例代ç è‡³å°‘会被å¤åˆ¶ç²˜è´´åˆ°ç”Ÿäº§ä»£ç ä¸­ä¸€æ¬¡ï¼Œå› æ­¤åœ¨ç¼–写代ç æ—¶åº”尽力而为。

答案 2 :(得分:5)

除了在演示编ç ç‚¹æ—¶æ··ä¹±ä»£ç çš„问题之外,我认为问题å˜æˆäº†ï¼Œ 你选择如何处ç†ç¤ºä¾‹ä»£ç ä¸­çš„错误?

也就是说,你åšä»€ä¹ˆï¼Ÿå¯¹äºŽä¸€ä¸ªåº”用程åºæ¥è¯´ï¼Œè‡´å‘½çš„是å¦ä¸€ä¸ªåº”用程åºæ˜¯éžè‡´å‘½çš„。例如如果我无法从网络æœåŠ¡å™¨ï¼ˆæ— è®ºæ˜¯404错误还是无å“应的æœåŠ¡å™¨ï¼‰æ£€ç´¢æŸäº›ä¿¡æ¯ï¼Œå¦‚果没有这些数æ®å°±æ— æ³•åšä»»ä½•äº‹æƒ…,这å¯èƒ½æ˜¯è‡´å‘½çš„。但如果这些数æ®æ˜¯ä½ æ­£åœ¨åšçš„事情的补充,那么也许你å¯ä»¥æ²¡æœ‰å®ƒã€‚

因此,上述内容å¯èƒ½ä»…指示记录错误。这比完全忽略错误è¦å¥½ã€‚但我认为通常困难在于知é“如何/何时(以åŠä½•æ—¶æ²¡æœ‰ï¼‰ä»Žé”™è¯¯ä¸­æ¢å¤ã€‚也许这本身就是一个全新的教程。

答案 3 :(得分:4)

示例应该是说明性的。他们应该始终尽å¯èƒ½å°‘地分散注æ„力。这是一个元例å­ï¼š

å‡è®¾æˆ‘们想è¦ä»Žæ–‡ä»¶ä¸­è¯»å–一个数字,添加3,然åŽå°†å…¶æ‰“å°åˆ°æŽ§åˆ¶å°ã€‚我们需è¦å±•ç¤ºä¸€äº›ä¸œè¥¿ã€‚

infile = file("example.txt")
content = infile.read()
infile.close()
num = int(content)
print (3 + num)
罗嗦,但是正确,除了有一些å¯èƒ½å‡ºé”™çš„事情。首先,如果文件ä¸å­˜åœ¨æ€Žä¹ˆåŠžï¼Ÿå¦‚果确实存在但ä¸åŒ…å«æ•°å­—会怎么样?

因此,我们将展示如何处ç†é”™è¯¯ã€‚

try:
    infile = file("example.txt")
    content = infile.read()
    infile.close()
    num = int(content)
    print (3 + num)
except ValueError:
    print "Oops, the file didn't have a number."
except IOError:
    print "Oops, couldn't open the file for some reason."

在显示如何处ç†ç”±æ­¤å¼•å‘的错误的几次迭代之åŽï¼Œæ–‡ä»¶å¤„ç†å’Œè§£æžã€‚当然,我们想展示一ç§è¡¨è¾¾tryå­å¥çš„更多pythonicæ–¹å¼ã€‚现在我们放弃错误处ç†ï¼Œå› ä¸ºè¿™ä¸æ˜¯æˆ‘们所展示的。

首先让我们消除ä¸éœ€è¦çš„é¢å¤–å˜é‡ã€‚

infile = file("example.txt")
print (3 + int(infile.read()))
infile.close()

由于我们没有写它,也ä¸æ˜¯é•¿æœŸè¿è¡Œè¿‡ç¨‹ä¸­çš„昂贵资æºï¼Œæ‰€ä»¥ä¿æŒå¼€æ”¾å®žé™…上是安全的。它将在程åºç»ˆæ­¢æ—¶å…³é—­ã€‚

print ( 3 + int(file("example.txt").read()))

然而,有些人å¯èƒ½è®¤ä¸ºè¿™æ˜¯ä¸€ä¸ªå习惯,并且有一个更好的方法æ¥å¤„ç†è¿™ä¸ªé—®é¢˜ã€‚我们å¯ä»¥ä½¿ç”¨ä¸Šä¸‹æ–‡æ¥ä½¿å®ƒæ›´æ¸…晰一些。当然,我们会解释一个文件将在一个withå—的末尾自动关闭。

with file("example.txt") as infile:
    print (3 + int(infile.read()))

然åŽï¼Œæ—¢ç„¶æˆ‘们已ç»è¡¨è¾¾äº†æˆ‘们想è¦çš„一切,那么我们将在本节的最åŽå±•ç¤ºä¸€ä¸ªå®Œæ•´çš„例å­ã€‚å¦å¤–,我们还会添加一些文档。

# Open a file "example.txt", read a number out of it, add 3 to it and print
# it to the console.
try:
    with file("example.txt") as infile:
        print (3 + int(infile.read()))
except ValueError: # in case int() can't understand what's in the file
    print "Oops, the file didn't have a number."
except IOError: # in case the file didn't exist.
    print "Oops, couldn't open the file for some reason."

这实际上是我通常看到指å—所表达的方å¼ï¼Œè€Œä¸”效果éžå¸¸å¥½ã€‚当任何部分缺失时,我通常会感到沮丧。

答案 4 :(得分:2)

我ä¸ç»å¸¸ä¸åŒæ„BWK,但我认为åˆå­¦è€…的例å­ç‰¹åˆ«æ˜¯åº”该显示错误处ç†ä»£ç ï¼Œå› ä¸ºè¿™æ˜¯åˆå­¦è€…很难解决的问题。更有ç»éªŒçš„程åºå‘˜å¯ä»¥å°†é”™è¯¯å¤„ç†è§†ä¸ºå·²è¯»ã€‚

答案 5 :(得分:2)

我认为解决方案ä½äºŽä¸­é—´ä½ç½®ã€‚如果è¦å®šä¹‰ä¸€ä¸ªå‡½æ•°æ¥æŸ¥æ‰¾åˆ—表'y'中的元素'x',则å¯ä»¥æ‰§è¡Œä»¥ä¸‹æ“作:

function a(x,y) 
{
   assert(isvalid(x))
   assert(isvalid(y))
   logic()
}

没有必è¦æ˜Žç¡®è¯´æ˜Žè¾“入有效的原因,åªæ˜¯è¯»è€…应该知é“逻辑å‡å®šæœ‰æ•ˆè¾“入。

答案 6 :(得分:1)

错误处ç†æœ¬èº«å°±æ˜¯ä¸€ç§èŒƒå¼;它通常ä¸åº”包括在示例中,因为它严é‡ç ´å了作者试图é‡åˆ°çš„é‡ç‚¹ã€‚

如果作者希望传递有关特定域或语言中的错误处ç†çš„知识,那么我更愿æ„作为读者有一个ä¸åŒçš„章节,其中概述了错误处ç†çš„所有主è¦èŒƒä¾‹ä»¥åŠè¿™å¯¹å…¶ä»–章节的影å“。

答案 7 :(得分:1)

我有一个想法是在你的示例代ç ä¸­åŒ…å«å¦‚下所示的行:

DONT_FORGET_TO_ADD_ERROR_CHECKING();   // You have been warned!

所有这一切都是为了阻止代ç ä¸ºç›²ç›®å¤åˆ¶å’Œç²˜è´´çš„人编写“è™è â€ï¼ˆå› ä¸ºæ˜¾ç„¶DONT_FORGET_TO_ADD_ERROR_CHECKING()没有在任何地方定义)。但这也很麻烦,å¯èƒ½ä¼šè¢«è§†ä¸ºç²—é²ã€‚

答案 8 :(得分:1)

我会说这å–决于具体情况。在åšå®¢æ–‡ç« æˆ–教科书中,我将专注于执行或演示所需功能的代ç ã€‚我å¯èƒ½ä¼šç»™å‡ºé”™è¯¯å¤„ç†çš„强制性点头,或许,甚至å¯ä»¥æ£€æŸ¥ä½†æ˜¯ç”¨çœç•¥å·æ¥å­˜å‚¨ä»£ç ã€‚在教学中,您å¯ä»¥é€šè¿‡åŒ…å«å¤ªå¤šä¸ç›´æŽ¥å…³æ³¨æ‰‹å¤´ä¸»é¢˜çš„代ç æ¥å¼•å…¥è®¸å¤šæ··æ·†ã€‚特别是在SO中,较短(但完整)的答案似乎是首选,因此在这ç§æƒ…况下处ç†â€œæ‰‹çš„波浪â€é”™è¯¯å¯èƒ½æ›´åˆé€‚。

也就是说,如果我æ供了一个å¯ä¾›ä¸‹è½½çš„代ç ç¤ºä¾‹ï¼Œæˆ‘通常会尽å¯èƒ½å®Œæ•´å¹¶åŒ…å«åˆç†çš„错误处ç†ã€‚这里的想法是,为了学习,这个人总是å¯ä»¥å›žåˆ°æ•™ç¨‹/åšå®¢å¹¶ä½¿ç”¨å®ƒæ¥å¸®åŠ©ç†è§£å®žé™…实现的代ç ã€‚

æ ¹æ®æˆ‘的个人ç»éªŒï¼Œè¿™æ˜¯æˆ‘对如何呈现TDD的问题之一 - 通常您åªä¼šçœ‹åˆ°å¼€å‘的测试,以检查代ç æ˜¯å¦åœ¨ä¸»è¦æ‰§è¡Œè·¯å¾„中æˆåŠŸã€‚我想看到更多的TDD教程包括为备用(错误)路径开å‘测试。我认为,这方é¢çš„测试是最困难的,因为它需è¦ä½ æ€è€ƒï¼Œè€Œä¸æ˜¯åº”该å‘生什么,而ä¸æ˜¯æ‰€æœ‰å¯èƒ½å‡ºé”™çš„事情。

答案 9 :(得分:1)

我è§è¿‡çš„一ç§æ–¹æ³•ï¼Œç‰¹åˆ«æ˜¯åœ¨Advanced Programming in the UNIX Environmentå’ŒUNIX Network Programming中的方法是用错误检查代ç åŒ…装调用,然åŽåœ¨ç¤ºä¾‹ä»£ç ä¸­ä½¿ç”¨åŒ…装器。例如:

ssiz_t Recv(...)
{
    ssize_t result;
    result = recv(...);
    /* error checking in full */
}

然åŽï¼Œåœ¨è°ƒç”¨ä»£ç æ—¶ï¼š

Recv(...);

这样你就å¯ä»¥æ˜¾ç¤ºé”™è¯¯å¤„ç†ï¼ŒåŒæ—¶å…许调用代ç æµæ¸…晰简æ´ã€‚

答案 10 :(得分:1)

我ä¸è®¤ä¸ºé”™è¯¯å¤„ç†åº”该在示例中,如果它模糊了逻辑。但是一些错误处ç†åªæ˜¯åšæŸäº›äº‹æƒ…的习惯用法,而在这ç§æƒ…况下包括它。

å¦å¤–,如果指出需è¦æ·»åŠ é”™è¯¯å¤„ç†ã€‚对于 deity 的喜爱也指出了需è¦å¤„ç†çš„错误。

这是阅读一些例å­ä¸­æœ€ä»¤äººæ²®ä¸§çš„部分。如果您ä¸çŸ¥é“自己在åšä»€ä¹ˆï¼ˆæˆ‘们必须å‡è®¾ç¤ºä¾‹çš„读者......),您ä¸çŸ¥é“è¦æŸ¥æ‰¾å“ªäº›é”™è¯¯ã€‚这将“添加错误处ç†â€å»ºè®®è½¬å˜ä¸ºâ€œæ­¤ç¤ºä¾‹æ— ç”¨â€ã€‚

答案 11 :(得分:0)

ä¸ï¼Œé™¤éžç¤ºä¾‹çš„目的是演示异常处ç†çš„一个方é¢ã€‚这是我的一个宠儿 - 许多例å­è¯•å›¾å±•ç¤ºæœ€ä½³å®žè·µå¹¶æœ€ç»ˆæ¨¡ç³Šå’Œå¤æ‚的例å­ã€‚我在代ç ç¤ºä¾‹ä¸­å§‹ç»ˆçœ‹åˆ°è¿™ä¸€ç‚¹ï¼Œé¦–先定义一组接å£å’Œç»§æ‰¿é“¾ï¼Œè¿™äº›ç¤ºä¾‹ä¸æ˜¯å¿…需的。过度å¤æ‚化的一个主è¦ä¾‹å­æ˜¯æˆ‘去年在TechEdåšè¿‡çš„动手实验。该实验室在Linq上,但是我被编写的示例代ç åˆ›å»ºäº†ä¸€ä¸ªå¤šå±‚应用程åºã€‚

示例应该从最简å•çš„代ç å¼€å§‹ï¼Œè¿™äº›ä»£ç æ¼”示了这一点,然åŽé€æ­¥è¿›å…¥å®žé™…使用和最佳实践。

顺便说一å¥ï¼Œå½“我è¦æ±‚求èŒè€…的代ç æ ·æœ¬æ—¶ï¼Œå‡ ä¹Žæ‰€æœ‰äººéƒ½å°å¿ƒç¿¼ç¿¼åœ°å±•ç¤ºä»–们对异常处ç†çš„知识:

public void DoSomethingCool()
{
    try
    {
         // do something cool
    }
    catch (Exception ex)
    {
        throw ex;
    }
}

我已ç»æ”¶åˆ°äº†æ•°ç™¾è¡Œä»£ç ï¼Œæ¯ä¸ªæ–¹æ³•éƒ½æ˜¯è¿™æ ·çš„。我已ç»å¼€å§‹ä¸ºä½¿ç”¨throw的人奖励积分;而ä¸æ˜¯æ‰”ex;

答案 12 :(得分:0)

示例代ç ä¸éœ€è¦åŒ…å«é”™è¯¯å¤„ç†ï¼Œä½†å®ƒåº”该演示正确的安全编ç æŠ€æœ¯ã€‚许多网络代ç æ®µéƒ½è¿å了OWASPå‰åå。