try catch throw的本质

try catch throw的本质解析

try catch 本质就是 gotothrow 本质就是 return ,没那么复杂。

你调用函数 foo() bar() ,判断返回值,然后进行错误处理:

...
    result = foo(...);
    if (error_occurs(result)) {
        handle_foo_error...;
        release_resources...;
    }
    ...
    result = bar(...);
    if (error_occurs(result)) {
        handle_bar_error...;
        release_resources...;
    }
    ...

你嫌麻烦,因为有很多重复语句,比如释放资源,那么你可以用goto语句简化:

...
    result = foo(...);
    if (error_occurs(result)) {
        error = foo_error;
        goto catch;
    }
    ...
    result = bar(...);
    if (error_occurs(result)) {
        error = bar_error;
        goto catch;
    }
    ...
catch:
    if (error == foo_error) {
        handle_foo_error...;
    } else if (error == bar_error) {
        handle_bar_error...;
    }
    release_resources...;

你还嫌 goto 太老土,或者有没有一种高级版的 goto 可以从内层函数跳出来?那你可以用stdc函数 setjmp() longjmp() ,不过这俩有bug,需慎用。而如果语言支持 try catch throw ,那么就简单多了:

try {
    result = foo(...); // foo_error在foo()里面throw
    ...
    result = bar(...); // bar_error在bar()里面throw
    ...
} catch (error) {
    if (error == foo_error) {
        handle_foo_error...;
    } else if (error == bar_error) {
        handle_bar_error...;
    }
    release_resources...;
}

我不喜欢那些让人云里雾里的术语,现在我就来告诉你们编译器/解释器是如何实现的:

首先,会标准化函数返回值,在其中嵌入一个隐藏的 success 布尔值标记, true 表示调用成功,返回值就是函数返回值, false 表示调用失败,那么返回值就是错误值(错误描述、堆栈信息…随便,反正都是值)。 throw 就是 return ,只不过会把 success 置为 false 。编译器/解释器发现如果函数调用处于 try 块里面,那么 successfalse 的时候,就会 gotocatch 块,否则就打印返回值(就是错误值)并退出进程。

c是根本没有上述标准化套路;go lua有,但让你自行处理;三脚猫c++因为不是高级语言,无法在返回值里嵌入隐藏字段,用的是 setjmp() longjmp() ?天晓得;至于java那种还把异常(错误?管它叫什么,反正就是返回值)各种分类,纯属吃饱撑的。

所以总结就是:本质都一样。随你喜好,想用就用,不想用就不用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值