【问题标题】:Erlang : Returning from a functionErlang:从函数返回
【发布时间】:2010-12-24 09:46:11
【问题描述】:

我有一个函数,其中有一系列单独的案例陈述。

case ... of
     ...
end,

case ... of
     ...
end,

...

等等

我想在其中一个 case 语句中出现特定 case 条件时立即从函数中返回 - 这样就不会检查下一个 case 语句,而函数只是退出/返回。我该怎么做?

【问题讨论】:

    标签: functional-programming erlang


    【解决方案1】:

    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 年了,所以我的语法可能不正确。

    【讨论】:

    • 请提供一个这样做的例子。
    • 示例已添加,希望对您有所帮助。
    【解决方案2】:

    一种方法是级联您的案例陈述:

    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;
    
    ...
    

    【讨论】:

      【解决方案3】:

      模式匹配是重构 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)

      【讨论】:

        【解决方案4】:

        使用捕捉/抛出

        来电者说:

        X = (catch foo(A, B))。

        然后写

        富(A,B)-> 案例...的 ...扔(X).. 结尾, 案例...的 ...投掷(Y) 结尾, ...

        这通常被认为是糟糕的编程习惯 - 因为该程序有多个 出口点,很难抓住

        【讨论】:

        • Throw in Erlang 专门用于非本地返回,而不是错误处理 - 所以原则上这是一种有效的方法。在实践中,我怀疑在这里进行重构以避免它会更好,但是如果没有看到代码就很难知道。
        • 原则上这可能是一种有效的方法,并且确实适用于非本地返回,但在代码中广泛使用它仍然是不好的做法。使用非本地返回会使其他程序员很难理解代码,并且更难调试。虽然它不是专门为错误处理而设计的,但错误处理通常是您应该使用它的唯一地方。此外,如果您正在编写错误处理代码,那么您并没有遵循 Erlang 的核心理念,即“成功代码”:您的思维更像是一个命令式程序员。
        【解决方案5】:

        我建议您进行重构以充分利用 Erlang 的强大功能及其模式匹配能力。

        没有return 运算符。此外,一个鲜为人知的事实是您可以执行以下操作:

        Return=case ... of

        case 语句可以有一个“返回”值。

        【讨论】:

        • 这就是为什么它被称为 case 表达式。
        • @jeffreyveon:我的回答能满足你的问题吗?
        • 是的,谢谢,感谢您帮助我开始使用 erlang :)
        【解决方案6】:

        在 Erlang 中,您只需使用模式匹配来触发相应的功能。如果您要涵盖和处理的子句太多,我还建议您稍微重构一下代码。

        【讨论】:

          猜你喜欢
          • 2018-12-06
          • 2020-08-11
          • 2017-06-23
          • 2013-02-28
          • 2019-06-14
          • 1970-01-01
          • 2013-01-03
          • 1970-01-01
          相关资源
          最近更新 更多