[Erlang01] 使用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了:)
2014年5月22日 12:10:16 补充:
1.不用try cathc怎么写一个复杂的Case :
case {check_name(Name),check_passwd(Passwd),check_url(Url) } of
{true ,true ,true} ->
do_next_work();
{false,_,_} ->
check_error(name);
{_,false,_} ->
check_error(passwd);
{_,_,false } ->
check_error(url)
end.
2. 有时会在一个重要的进程 时最底层做了try catch ,以防止carsh ,那我们在写上层逻辑时,也会做复杂的判定,又加了一个try catch,
例如:
%%在try catch中再套try catch.
init_data(Data) ->
try
Data1 = init_data2(Data),
after_init(Data1)
catch _:_ -> error
end.
init_data2(Data) ->
try
check_init_data(Data)
catch _:_ -> init_erro
end.
值得优化:只在最底层用try catch把所有的错误都放到这里统一处理。
[Erlang01] 使用catch与try catch避免嵌套nest_case的更多相关文章
- 在finally块中使用try catch,并且catch的时候抛出异常的一个问题
在finally中使用try/catch,并且catch的时候抛出异常 IDEA会提示警告 Reports throw statements inside of finally blocks. Whi ...
- try catch里面try catch嵌套
try catch里能否内嵌try catch?答案是肯定的.但是等内层try catch出异常之后是个什么执行顺序呢?看下面代码 static void Main(string[] args) { ...
- php中设定一个全局异常处理。全局catch。默认catch。默认异常处理
<?php function handleMissedException($e) { echo "Sorry, something is wrong. Please try again ...
- erlang的catch和 try catch的初步猜测
一. catch(Fun):似乎可以避免因为 函数Fun内的错误而造成的当前的进程的崩溃.
- 如何处理异常? catch Exception OR catch Throwable
在Java中,当你需要统一处理异常的时候,你是会选择catch (Exception),还是直接catch (Throwable)? Java的异常体系 Throwable: Java中所有异常和错误 ...
- C++异常处理:try,catch,throw,finally的用法
写在前面 所谓异常处理,即让一个程序运行时遇到自己无法处理的错误时抛出一个异常,希望调用者可以发现处理问题. 异常处理的基本思想是简化程序的错误代码,为程序键壮性提供一个标准检测机制. 也许我们已经使 ...
- C++异常处理: try,catch,throw,finally的用法
写在前面 所谓异常处理,即让一个程序运行时遇到自己无法处理的错误时抛出一个异常,希望调用者可以发现处理问题. 异常处理的基本思想是简化程序的错误代码,为程序键壮性提供一个标准检测机制. 也许我们已经使 ...
- [转载]java中try 与catch的使用
留着以后看 原文地址:与catch的使用">java中try 与catch的使用作者:碌碌如玉 try{ //代码区 }catch(Exception e){ //异常处理 } 代码区 ...
- 【转】 SQL 2005 try catch
1 TRY…CATCH 1.1 用法 TRY…CATCH的语法如下: BEGIN TRY -- TRY 模块 -- 业务处理 END TRY BEGIN CATCH -- CATC ...
随机推荐
- Installation failed with message Failed to finalize session : INSTALL_FAILED_INVALID_APK: Split lib_slice_8_apk was defined multiple times. It is possible that this issue is resolved by uninstalling a
取消:Instant Run就行
- c# var的含义与用法
VAR 是3.5新出的一个定义变量的类型其实也就是弱化类型的定义VAR可代替任何类型编译器会根据上下文来判断你到底是想用什么类型的至于什么情况下用到VAR 我想就是你无法确定自己将用的是什么类型就可以 ...
- 为什么是static?
为什么是static因为系统开始执行一个程序前,并没有创建main()方法所在类的实例对象,它只能通过类名类调用主方法. public static void main(String args[])我 ...
- 大神的---解决tomcat内存溢出问题----tomcat报错:This is very likely to create a memory leak问题解决
tomcat memory leak解决方案 这种问题在开发中经常会碰到的,看看前辈的总结经验 Tomcat内存溢出的原因 在生产环境中tomcat内存设置不好很容易出现内存溢出.造成内存溢出是不一 ...
- ORA-00604: 递归 SQL 级别 1 出现错误 ORA-01000: 超出打开游标的最大数
有程序没关闭游标, --打开了哪些游标 select * from v$open_cursor 在open cursor之后一定要注意要close cursor(在store procedure里更应 ...
- Professional C# 6 and .NET Core 1.0 - Chapter 43 WebHooks and SignalR
本文内容为转载,重新排版以供学习研究.如有侵权,请联系作者删除. 转载请注明本文出处:Professional C# 6 and .NET Core 1.0 - Chapter 43 WebHooks ...
- 接口自动化 Windows + HttpRunner 初探(一)
运行环境 HttpRunner 是一个基于 Python 开发的测试框架,可以运行在 macOS.Linux.Windows 系统平台上. HttpRunner 的开发环境为 macOS + Pyth ...
- Oracle 日志报错导致的 “没有登录” 问题
遇到的问题是日志空间满了,导致Oracle无法登陆,但用PL/SQL登录仅会提示“没有登录” # 首先检查日志空间是否满了,并删除过期日志 rman target sysdba/password@or ...
- DBArtist之Oracle入门第2步: 了解Oracle的Database Control
之前安装好数据库后,会有下面这个弹窗,然后根据Database Control URL地址进入瞧一瞧,看一看! 根据地址进入以后,是一个登录界面,用system账户登录,密码就是安装Oracle的时候 ...
- 关于sudo apt-get update错误 http://archive.canonical.com natty InRelease
sudo apt-get update 错误 http://archive.canonical.com natty InRelease 错误 http://mirror.rootguide.org n ...