exception - 在一系列 Erlang 匹配中,我如何判断哪一个失败了?

标签 exception erlang pattern-matching

考虑以下代码片段:

do_stuff() ->
    % assume each of BoundVarI is bound here
    BoundVar1 = term1(),
    BoundVar2 = term2(),
    % ...
    BoundVarN = termN(),
    ok.

do_stuff_wrapper() ->
    do_stuff().

在包装函数 (do_stuff_wrapper/0) 中,我到底如何确定哪一个匹配失败了?需要明确的是,我并不是在寻找一种方法来告诉它只是失败了,可能是通过生成和监视一个进程,而是一种方法来告诉哪个导致比赛失败。我考虑的一种方法是从错误元组中提取行号,但我觉得这会严重损害可维护性。

最佳答案

您可以尝试以下方法:

ScopeRef = make_ref(), %% To make sure to catch only errors in this scope
try
  {_, BoundVar1} = {{ScopeRef, term1}, term1()},
  {_, BoundVar2} = {{ScopeRef, term2}, term2()},
  {_, BoundVarN} = {{ScopeRef, termN}, termN()},
  %% ^ Consider turning this into a lists:foreach/recursion
  ok
catch %% First error stops execution
  error:{badmatch, {{ScopeRef, FailedFunName}, _FailedTerm}} -> {error, {nomatch, FailedFunName}}
end.

或者,如果您想检查每一个

BoundTerms = [BoundVar1, BoundVar2, BoundVarN],
AssertFuns = [fun term1/0, fun term2/0, fun termN/0],
FailedTerms = lists:reverse(lists:foldl(fun({BoundVar, AssertFun} = Pair, Acc) ->
  case AssertFun() of
    BoundVar -> Acc;
    _ -> [Pair | Acc]
  end
end, [], lists:zip(BoundTerms, AssertFuns)),
case FailedTerms of
  [] -> ok;
  _ -> exit({assert_failed, FailedTerms})
end.

根据实际问题,我会选择其中之一(或都不选择),但这些示例显示了您可以调整的不同方法。

关于exception - 在一系列 Erlang 匹配中,我如何判断哪一个失败了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65709853/

相关文章:

Visual Studio 2017 中未捕获 C++ 异常

java - 如何在java约束测试违规中拦截并处理(FOREIGN KEY约束失败)

string - Haskell 中二进制文件和位串的模式匹配/解构,类似于 Elixir/Erlang 中的模式匹配/解构

埃尔兰;形成大量重复整数

java - 如何使用 Vavr 在 Java 中模式匹配具有定义类型的 Option 元组

javascript - 如何在带有模式的文本中查找数字并在 JavaScript 中更改它

Python tarfile 模块在提取过程中覆盖现有文件 - 如何禁用它?

c# - 错误处理: Raise Events or Manually Throw Exception

serialization - Erlang序列化库

python - 正则表达式按字面和被动方式匹配换行符