循环中的错误

时间:2011-01-30 18:48:14

标签: erlang erlang-driver

在列表的每个元素上给出以下循环:

lists:foldl(fun(X) -> ... end,N,Y),

如何捕获错误并继续循环元素?

同样的问题,如果这个代码在gen_server中,如果process_flag(trap_exit,true)?

2 个答案:

答案 0 :(得分:3)

为什么你不能像这样使用try/catch

1> lists:foldl(
1>     fun (E, A) ->
1>         try E + A
1>         catch
1>             _:_ ->
1>                 A
1>         end
1>      end, 0, [1, 2, 3, 4, a, 6]).
16

或者,如果要提取错误处理,可以使用装饰器功能,如下所示:

1> Sum = fun (E, A) -> E + A end.
#Fun<erl_eval.12.113037538>
2> HandlerFactory = fun (F) ->              
2>     fun (E, A) ->
2>         try F(E, A)
2>         catch
2>             _:_ ->
2>                 A
2>         end
2>     end
2> end.
#Fun<erl_eval.6.13229925>
3> lists:foldl(HandlerFactory(Sum), 0, [1, 2, 3, 4, a, 6]).
16
4> Mul = fun (E, A) -> E * A end.
#Fun<erl_eval.12.113037538>
5> lists:foldl(HandlerFactory(Mul), 1, [1, 2, 3, 4, a, 6]).
144

答案 1 :(得分:0)

@hdima的第一个建议是最简单的,让你完全控制如何处理不同的错误/抛出等。例如,你可能希望允许从foldl作为非本地退出的形式抛出。你真的确定要忽略错误吗?

HandlerFactory虽然有一个过于复杂的OO感觉,但看起来有点偏。 :-)它也严重限制了你的选择。

此代码将在gen_server内工作,因为它的效果完全是本地的。陷阱退出不会影响这一点,也不会受其影响,因为退出是来自其他进程的信号,try不会捕获这些信号。启用trap_exit会导致其他进程的所有退出信号在本地转换为使用receive作为任何其他消息进行访问的消息。