案例检查清单是否为空,而不是递归? [英] Case to check when list is empty rather then recursion?

查看:190
本文介绍了案例检查清单是否为空,而不是递归?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图检查一个案例如果一个列表是空的,而不是循序渐进地捕捉模式,这是正确的方式去Erlang或我只是走下错误的路径和模式匹配是最好的方式如果清单已经被清空,可以捕获?

Im trying to check with a case if a list is empty rather then recursivly catching the pattern when it is, is this the right way to go in Erlang or am i just walking down the wrong path and pattern matching is the best way to catch if a list has been emptied or not?

     calculate([Head|Tail], pi, x, y) ->
         ...calculations of Head being sent to a list...
         case Tail == [] of
            false ->
               calculate(Tail, pi, x, y)
         end.

或者我应该只是模式匹配计算如果列表是空的?

or should i just pattern match on calculate if the list is empty?

推荐答案

您的代码错误



一般做法是使用功能子句与模式匹配。它的工作原理就是这样,它被认为更加可读。它修复了您在执行中出现的一个错误:

Error in your code

General practice is to use function clause with pattern match. It works just as case, and it is considered to much more readable. And it fixes one error you have in your implementation:

首先,您的代码可以以这种方式重写。

First of all your code could be rewritten in this manner.

calculate([Head|Tail], pi, x, y) ->
  %% ... actual calculations ...
  calculate( Tail, pi, x, y);
calculate([], pi, x, y) ->
  %% you need to return something here, but you don't

看到,其中一个子句不返回任何东西,这在Erlang中是不允许的(在编译期间失败)。你的实现是完全一样的。 case 就像Erlang中的任何东西都必须返回一些值(并且由于它是函数中的lase语句,所以这个值将从函数返回)。而且由于 case 需要返回某些东西,所以需要匹配其中一个子句。大多数情况下,由于 Tail == [] 将返回 false 这不会是一个问题。但是最后递归调用时,当 Tail 为空列表时, Tail == [] 将返回 true case 不匹配任何东西。在Erlang中,这将导致(抛出或退出确切) case_clause 错误。所以你的实现总是会失败。

As you can see, one of clauses do not return anything, which is not allowed in Erlang (fail during compilation). Your implementation does exactly same thing. case just like anything in Erlang must return some value (and since it is lase statement in your function this value will be returned from function). And since case needs to return something, it needs to match on one of it's clauses. It most cases, since Tail == [] will return false it will not be a problem. But at last recursive call, when Tail is empty list, Tail == [] will return true and case will not match to anything. And in Erlang this will cause (throw, or exit to be exact) case_clause error. So your implementation will always fail.

要解决它,你需要确保你总是有一些匹配的情况,像这样

To fix it you need to make sure you always have something matching in you case, like this

case Tail == [] of
  false ->
    calculate(Tail, pi, x, y)
  true ->
    %% return something 
end.

或者可以这样写

case Tail of
  [] ->
    %% return something sane
  _ -> 
    calculate(Tail, pi, x, y)
end.

其中 _ 将匹配任何东西,会像 else 有些其他语言。最后,它可以用函数子句编写,就像我之前展示的那样,但是返回了这个理智的值。

where _ will match to anything, and will work somewhat like else is some other languages. And finally it could be written with function clauses, just like I showed before, but with this sane value returned.

strong>编辑

EDIT

如果你现在看看我们的代码Wright只返回一个值;最后一个递归调用(一个我称为正常)。如果您想要考虑所有递归电话的所有计算,您需要以某种方式累积它们。为此,我们将使用 Acc 变量

If you look closer at our code wright now we are returning only one value; the one from last recursive call (the one I called "sane"). If you would like to take under account all calculations from all recursive calls you need to accumulate them somehow. And to do this we will use Acc variable

calculate([Head|Tail], pi, x, y, Acc) ->
  %% ... actual calculations with result assigned to Res variable ...
  NewAcc = [Res | Acc]
  calculate(Tail, pi, x, y, NewAcc);
calculate([], pi, x, y, Acc) ->
  Acc.

在每个递归调用中,我们添加了我们的计算 Res 到累加器 Acc ,并将此更新列表发送到下一级递归。最后,当我们的输入列表为空(我们处理所有数据)时,我们只返回整个累加器。所有我们需要做的是确保,当计算被首先调用时,它被调用空列表为 Acc 。这可以通过新的(稍旧的)函数来完成。

In each recursive call we add our calculations Res to accumulator Acc, and send this updated list to next level of recursion. And finally, when our input list is empty (we processed all data) we just return whole accumulator. All we need to do, is make sure, that when calculate is being first called, it is called with empty list as Acc. This could be done by new (somewhat old) function

calculate(List, pi, x, y) ->
   calculate(List, pi, x, y, _Acc = []).

现在我们可以导出 calculate / 4 保留 calculate / 5 private。

Now we can export calculate/4 and keep calculate/5 private.

这篇关于案例检查清单是否为空,而不是递归?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆