首页 > 代码库 > [Erl_Question01] 使用catch与try catch避免嵌套nest_case
[Erl_Question01] 使用catch与try catch避免嵌套nest_case
catch 如此好用,为什么官方还是推荐用try catch?
1. catch 的用法非常简单:
catch case do_check(Test) of {ok,Result} -> do_thing(Result); {error,ErrReason} -> do_error(ErrReason) end. do_check(Test) -> case Test of 1 -> erlang:throw({error,to_small}); 2 –> {ok,2}; 9 -> erlang:throw({error,too_big}) end,
以上用法的优点是:非常简单&&do_check/1里面如果有nest_case也可以处理掉,
缺点也非常明显:
1.1 如果Test是除1,2,9以外的值时会发生case_clause,catch也不能匹配;
1.2 do_check/1要在外层用Catch[这个check要由调用者来确定用法],这就对调用者有更高的要求。
2. try catch用法:
%% 首先对FuncOrExpressionSequence求值 %% 如果没有产生异常则顺序进行Patterm匹配, 匹配成功后执行后面的表达式 %% 如果有异常抛出, 则顺序匹配ExPattern(ExceptionType是throw、exit、error中的一个, 默认为throw) %% after块中的代码用于清理工作,绝对会执行 try FuncOrExpressionSequence of Pattern1 [when Guard1] ->Expressions1; Pattern2 [when Guard2] ->Expressions2; ... catch ExceptionType: ExPattern1 [when ExGuard1] ->ExExpressions1; ExceptionType: ExPattern2 [when ExGuard2] ->ExExpressions2; ... after AfterExpressions end.
也可以把after后面的去掉:
%% 将三种异常方式依次捕获 try F catch throw: X ->ExExpressions1; exit: X ->ExExpressions2; error: X ->ExExpressions3 end.
那么根据这用法:可以把Catch的用法改写会:
case do_check(Test) of {ok,Result} -> do_thing(Result); {_,ErrReason} -> do_error(ErrReason) end. do_check(Test) -> try case Test of 1 -> erlang:throw({error,to_small}); 2 –> {ok,2}; 9 -> erlang:throw({error,too_big}) end catch throw:X -> {throw,X}; exit:X -> {exit,X}; error:X -> {error,X} end.
从上面可以看出:所有的异常都被正确的处理了且do_check/2对调用者也是透明的!真是太棒了!
在stack overflow上这个答案才能是最佳实践:
how to write_elegantly_check_function
从上面测试结果来看,try catch确定会消耗一点性能,所以如果条件不复杂且频繁调用的check,就不要用try catch了:)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。