我有一个逻辑函数,如下所示:
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()
实际上是2行代码,我最近不得不在所有可能的退出中添加第三行代码。有没有更优雅的方式来组织这个代码?我不能只使用finally
,因为并不总是抛出异常。
答案 0 :(得分:10)
你可以使用终结,即使没有抛出任何异常,AFAIK这是做你想做的最优雅的方式。
答案 1 :(得分:2)
不需要抛出异常来调用finally
块。该块的重点是可靠地调用始终。你可以用它。
答案 2 :(得分:1)
无论是否抛出异常,都会执行finally
子句,因此您可以将代码包装在try / catch / finally的多个级别中...(这是C#,因为你没有' t指定一种语言)
try
{
try
{
something();
}
catch
{
// Err handler for something
}
}
finally
{
endstuff(); // this code always runs
}
答案 3 :(得分: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
答案 4 :(得分: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
只会检查最后一次返回结果的错误值。
答案 5 :(得分:0)
由于每次都会返回endstuff(),因此您不必将返回呼叫短路。该函数将返回endstuff(),无论发生什么,为什么将代码放在每个检查中?如果有错误,除非你不想做 doStuff4()。
更优雅的方法可能是在finally块中执行endstuff()并将该值赋给变量,然后在结尾返回该变量。
答案 6 :(得分: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();
}