在列表的每个元素上给出以下循环:
lists:foldl(fun(X) -> ... end,N,Y),
如何捕获错误并继续循环元素?
同样的问题,如果这个代码在gen_server中,如果process_flag(trap_exit,true)?
答案 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
作为任何其他消息进行访问的消息。