语言设计(例外):为什么“尝试”?

时间:2014-02-12 00:05:30

标签: exception-handling programming-languages language-design

在我看过异常的语言(C ++,Java,Javascript,Python,PHP,...)中,我总是看到try或类似的东西来标记{{1的范围}}。我想知道是否有必要。没有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);
}

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

1 个答案:

答案 0 :(得分:4)

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

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

例如,这是有效的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 { {1}})。您可以使它不能在}\n范围之外立即执行变量声明,但是如果没有类似catch块之类的东西,则无法做很多事情。你可以要求在运行任何可以抛出的东西之前声明作用域中的所有变量(类似于旧的C),但这会在构造代码时带来一些自由,并使其更难阅读。