3

在我看到异常(C++,Java,Javascript,Python,PHP等)的语言中,我总是看到try或类似的东西来标记catch的范围。我想知道是否有必要。 try块有什么设计问题?语言设计(例外):为什么`尝试`?

例如,借此:

try{ 
    try{ 
     do_something_dangerous0(); 
    }catch (SomeProblem p){ 
     handle(p); 
    } 
    try{ 
     do_something_dangerous1(); 
    }catch (SomeProblem p){ 
     handle(p); 
    } 
}catch (SomeOtherProblem p){ 
    handle(p); 
} 

我想象这作为替代。

do_something_dangerous0(); 

catch (SomeProblem p){ 
    handle(p); 
} 

do_something_dangerous1(); 

catch (SomeProblem p){ 
    //catches from only the second unless the first also threw 
    handle(p); 
} 

catch (SomeOtherProblem p){ 
    //catches from either, because no other block up there would 
    handle(p); 
} 

如果你想避免块醒目“太多”,你可以做一个新的范围:

do_something_dangerous2(); 

{ 
    do_something_dangerous3(); 

    catch (SomeProblem p){ 
     //does not catch from do_something_dangerous2() 
     //because if that throws, it won't reach in here 
     handle(p); 
    } 
} 

catch (SomeProblem p){ 
    handle(p); 
} 

catch (SomeOtherProblem p){ 
    handle(p); 
} 

(我为什么这不会对语言,如C工作答案++和Java ,至少在下面发布为答案,但我没有针对动态语言的答案。)

+0

在一般情况下,您需要精确定界异常处理范围的开始和结束。人们可以为此使用“孤独”的范围,但它不会真正改变任何事情,并且不太清楚。 –

+0

(我曾经在一个使用BEGIN/NIGEB宏定义异常处理范围的系统上工作,但总体结构几乎与try/catch/finally完全相同,该函数决定语法,而不是其他方法。) –

+0

我是不是用'如果你想避免一个障碍物'太多'......'呢? – leewz

回答

4

对于至少需要变量声明的语言来说,它不起作用。

try块中的任何语句都可能无法完全执行,包括变量的声明和初始化。在具有块范围界定的语言中,尤其是需要变量声明(如C++,Objective C和Java)的语言时,catch块不共享try块的范围,因此不允许访问try的局部变量。 try -less系统会破坏范围规则。

例如,这是有效的C++代码。

try{ 
    int x = some_func(); 
    int y = some_other_func(); 
}catch(SomeException){ 
    //... 
} 

如果换算成,

int x = some_func(); 
int y = some_other_func(); 

catch(SomeException){ 
    //... 
} 

然后,下支架范围规则,xy是在范围内的catch块,即使他们可能不声明/尚未初始化。

您可以更改作用域规则,使catch不会看到这些变量声明,但是这是一个非常简单和普遍规则的主要并发症,以节省大约七个字符(try{\n}\n)。你可以这样做,以便你不能立即在catch的范围外进行变量声明,但是如果没有像try这样的块,那么你就不能做很多事情。你可以在运行任何可以抛出的东西(类似于旧C)之前声明一个范围中的所有变量,但是这会在构造代码时带来一些自由,并且使其更难以阅读。