2010-01-15 38 views
2

我有逻辑的功能,看起来像这样:模式:在函数退出时执行某些操作的优雅方法?

doStuff1() 
try: 
    doStuff2() 
except type1: 
    error1() 
    return endstuff() 
except type2: 
    error2() 
    return endstuff() 
except: 
    error3() 
    return endstuff() 

if doStuff3(): 
    error4() 
    return endstuff() 

doStuff4() 
return endstuff() 

正如你所看到的,是endstuff()在一切可能的退出功能来完成。现在,endstuff()实际上是两行代码,最近我不得不为所有可能的退出添加第三行代码。有没有更优雅的方式来组织这些代码?我不能只使用finally,因为抛出异常并不总是这样。

回答

10

可以即使没有抛出任何异常,也可以使用最后一个,AFAIK这是最优雅的方式来做你想做的事。

+0

我知道,但这仍然会有3个重复 - 最后一个,if中的一个,以及函数结尾的一个。我可以将这3个变成一个实例吗?如果endstuff()是5-6行仍然是重复的代码行。你是说我把所有的代码都放在一个单独的try ... finally块中? – Claudiu 2010-01-15 20:09:28

+0

heh我很蠢。你的意思最终不是我的'尝试'的补充,而是围绕着整个代码。我也忘记了即使在函数退出时,终于可以调用。 – Claudiu 2010-11-29 21:42:30

2

对于要调用的finally块,不需要抛出异常。该块的整点是它可靠地调用总是。你可以使用这个。

1

A finally子句将执行,无论是否抛出异常,所以你可以将你的代码包装在try/catch/finally的多个层次中......(这是C#,因为你没有指定一个语言)

try 
{ 
    try 
    { 
     something(); 
    } 
    catch 
    { 
     // Err handler for something 
    } 
} 
finally 
{ 
     endstuff(); // this code always runs 
} 
+1

我认为值得指出的是,甚至还有'try ... finally'结构,它们根本不需要* catch存在。这种语言结构只有在没有捕获到异常时才会执行'finally'块。你的代码示例很好地演示了这一点。 – stakx 2010-01-15 19:42:36

0

由于每次都返回endstuff(),所以不必短路返回呼叫。该函数将返回endstuff(),无论发生什么情况,为什么在每次检查中放置该代码?除非你不想做doStuff4()如果有错误。

更优雅的方式可能是在finally块中执行endstuff()并将该值赋给变量,然后在最后返回该变量。

1

根据不同的语言,这是RAII的理想选择。例如,在堆栈中分配一个对象,并在其析构函数中执行“endstuff()”;这样它就会在范围的最后被调用。

class something 
    def ~something() 
     darkside() 
     endstuff() 


// in the function 
def somefunc() 
    something s 

    doStuff1() 
    try: 
     doStuff2() 
    except type1: 
     error1() 
     return 
    except type2: 
     error2() 
     return 
    except: 
     error3() 
     return 

    if doStuff3(): 
     error4() 
     return 

    doStuff4() 
    return 

+0

@Claudiu虽然不支持GC语言,但... – 2010-04-16 17:55:16

1

我赞成finally块,但只是作为一种替代你可以使用一个while块如:

while(true) 
    doStuff1() 
    try: 
     doStuff2() 
    except type1: 
     error1() 
     break 
    except type2: 
     error2() 
     break 
    except: 
     error3() 
     break 

    if doStuff3(): 
     error4() 
     break 

    doStuff4() 
end while 

return endstuff() 

,如果你使用的是做一个语言,这是有用不支持例外。在这种情况下,您的except type只会检查上次返回结果的错误值。

0

关于'finally'子句的其他评论是正确的,但是当我没有'finally'子句可用时(并非所有语言都可以),我将多退出代码分解为子功能。这不仅适用于try/catch,还适用于需要检查许多条件并且要避免深度嵌套的'if'子句的代码。这个例子显示了两个:

ThingOne() { 
    var foo; 
    foo.open(); 

    if (ThingTwo(foo)) 
     ThingThree(foo); 

    foo.close(); 
} 

ThingTwo(var x) { 
    try 
    { 
     ...normal case... 
     return true 
    catch x1 
     handlex1(); 
    catch x2 
     handlex2(); 
    } 
    return false; 
} 

ThingThree(var x) { 
    if (x.conditionOne == false) return; 
    if (x.conditionTwo == true) return; 
    ...etc... 
    x.GoForIt(); 
} 
相关问题