首页 > Erlang并发教程 > 8.3 Erlang并发编程-使用catch和throw实现函数的非本地返回
2013
11-15

8.3 Erlang并发编程-使用catch和throw实现函数的非本地返回

BACK TOP文章索引

  1. 使用catch和throw实现函数的非本地返回
  2. 共2条评论

使用catch和throw实现函数的非本地返回

假设我们要编写一个用于识别简单整数列表的解析器,可以编写如下的代码:

parse_list(['[',']' | T])
    {nil, T};
parse_list(['[', X | T]) when integer(X) ->
    {Tail, T1} = parse_list_tail(T),
    {{cons, X, Tail}, T1}.

parse_list_tail([',', X | T]) when integer(X) ->
    {Tail, T1} = parse_list_tail(T),
    {{cons, X, Tail}, T1};
parse_list_tail([']' | T]) ->
    {nil, T}.

例如:

> parse_list(['[',12,',',20,']']).
{{cons,12,{cons,20,nil}},[]}

要是我们试图解析一个非法的列表,就会导致如下的错误:

> try:parse_list(['[',12,',',a]).
!!! Error in process <0.16.1> in function
!!!     try:parse_list_tail([',',a])
!!! reason function_clause
** exited: function_clause **

如果我们想在跳出递归调用的同时仍然掌握是哪里发生了错误,可以这样做:

parse_list1(['[',']' | T]) ->
    {nil, T};
parse_list1(['[', X | T]) when integer(X) ->
    {Tail, T1} = parse_list_tail1(T),
    {{cons, X, Tail}, T1};
parse_list1(X) ->
    throw({illegal_token, X}).

parse_list_tail1([',', X | T]) when integer(X) ->
    {Tail, T1} = parse_list_tail1(T),
    {{cons, X, Tail}, T1};
parse_list_tail1([']' | T]) ->
    {nil, T};
parse_list_tail1(X) ->
    throw({illegal_list_tail, X}).

现在,如果我们在catch里对parse_list/1求值,将获得以下结果:

> catch parse_list1(['[',12,',',a]).
{illegal_list_tail,[',',a]}

通过这种方式,我们得以从递归中直接退出,而不必沿着通常的递归调用路径逐步折回。


8.3 Erlang并发编程-使用catch和throw实现函数的非本地返回》有 2 条评论

  1. 哇,看来是还没有毕业的同学呀,加油加油了

  2. 哇,看来是还没有毕业的同学呀,加油加油了

留下一个回复

你的email不会被公开。