Ошибки в цикле

Дан следующий цикл для каждого элемента списка:

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

Как отловить ошибки и продолжить зацикливаться на элементах?

Тот же вопрос, если этот код находится в gen_server и если process_flag(trap_exit, true)?

2 ответа

Решение

Почему вы просто не можете использовать 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

Первое предложение @hdima является самым простым и дает вам полный контроль над тем, как обрабатывать различные ошибки / броски и т. Д. Например, вы можете разрешить бросать как форму нелокального выхода из сгиба. Вы действительно уверены, что хотите игнорировать ошибки?

Хотя HandlerFactory имеет слишком сложный внешний вид и кажется немного не в себе.:-) Это также сильно ограничивает ваши возможности.

Этот код будет работать в gen_server так как его эффект чисто локальный. Захват выходов не повлияет на это или не повлияет на него, так как выходы являются сигналами других процессов, и они не перехватываются try, Включение trap_exit приводит к тому, что все сигналы выхода из других процессов локально преобразуются в сообщения, доступ к которым осуществляется с помощью receive как любое другое сообщение.

Другие вопросы по тегам