Ошибки в цикле
Дан следующий цикл для каждого элемента списка:
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
как любое другое сообщение.