【发布时间】:2010-12-24 09:46:11
【问题描述】:
我有一个函数,其中有一系列单独的案例陈述。
case ... of
...
end,
case ... of
...
end,
...
等等
我想在其中一个 case 语句中出现特定 case 条件时立即从函数中返回 - 这样就不会检查下一个 case 语句,而函数只是退出/返回。我该怎么做?
【问题讨论】:
标签: functional-programming erlang
我有一个函数,其中有一系列单独的案例陈述。
case ... of
...
end,
case ... of
...
end,
...
等等
我想在其中一个 case 语句中出现特定 case 条件时立即从函数中返回 - 这样就不会检查下一个 case 语句,而函数只是退出/返回。我该怎么做?
【问题讨论】:
标签: functional-programming erlang
Erlang 没有return 运算符。您需要将代码重构为更小的函数。
您的原始代码有两个用逗号运算符链接的 case 表达式。我认为您在要保留的第一个 case 表达式中有一些副作用。下面,我使用了一个虚构的return 运算符:
case ... of
P1 -> return E1;
P2 -> E2;
end,
case ... of
...
end
这样的表达式可以使用小函数和类似这样的模式匹配转换为真正的 Erlang 代码:
case1(P1, ...) -> E1;
case1(P2, ...) -> E2, case2(...).
case2(...) -> ...
免责声明:我写 Erlang 代码已经 10 年了,所以我的语法可能不正确。
【讨论】:
一种方法是级联您的案例陈述:
my_fun(X) ->
case cond1(X) of
true -> ret1;
_ ->
case cond2(X) of
true -> ret2;
_ ->
...
end
end.
另一个是将你的case语句分成子句:
my_fun(X) ->
my_fun(cond1, X).
my_fun(cond1, X) ->
case cond1(X) of
true -> ret1;
_ -> my_fun(cond2, X)
end;
my_fun(cond2, X) ->
case cond2(X) of
true -> ret2;
_ -> my_fun(cond3, X)
end;
...
【讨论】:
模式匹配是重构 case 语句的好方法——你可以这样做
testcase(1, X, Y) -> .... passed1;
testcase(2, X, Y) -> .... passed2;
testcase(N, X, Y) when N > 2 -> .... passedlarge;
testcase(_, X, Y) -> defaultcase.
然后你的case语句简单地总结为:
X = testcase(Number, Param1, Param2).
(在这个人为的例子中,X 将被传递 1、passed2、passedlarge 或 defaultcase)
【讨论】:
使用捕捉/抛出
来电者说:
X = (catch foo(A, B))。然后写
富(A,B)-> 案例...的 ...扔(X).. 结尾, 案例...的 ...投掷(Y) 结尾, ...这通常被认为是糟糕的编程习惯 - 因为该程序有多个 出口点,很难抓住
【讨论】:
我建议您进行重构以充分利用 Erlang 的强大功能及其模式匹配能力。
没有return 运算符。此外,一个鲜为人知的事实是您可以执行以下操作:
Return=case ... of
case 语句可以有一个“返回”值。
【讨论】:
在 Erlang 中,您只需使用模式匹配来触发相应的功能。如果您要涵盖和处理的子句太多,我还建议您稍微重构一下代码。
【讨论】: