3

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

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

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

如果此代码在 gen_server 中以及 process_flag(trap_exit, true) 是否存在同样的问题?

4

2 回答 2

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
于 2011-01-30T20:38:22.743 回答
0

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

HandlerFactory 虽然对它有一种过于复杂的 OO 感觉,而且似乎有点不对劲。:-) 它也严重限制了您的选择。

此代码将在 a 内工作,gen_server因为它的效果纯粹是本地的。捕获出口不会影响这一点,也不会受到它的影响,因为出口是来自其他进程的信号,而这些信号不会被try. 打开trap_exit会导致来自其他进程的所有退出信号在本地转换为可以receive作为任何其他消息访问的消息。

于 2011-01-31T15:55:24.927 回答