gpt4 book ai didi

erlang - 当列表为空时检查而不是递归的情况?

转载 作者:行者123 更新时间:2023-12-02 08:14:32 25 4
gpt4 key购买 nike

我试图检查一个列表是否为空的情况,而不是在它为空时递归地捕获模式,这是进入 Erlang 的正确方法还是我只是走在错误的道路上,模式匹配是最好的方法捕获列表是否已清空?

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

或者如果列表为空,我应该只进行模式匹配计算吗?

最佳答案

代码错误

一般做法是使用带有模式匹配的函数子句。它的工作原理与 case 一样,并且被认为更具可读性。它修复了您在实现中遇到的一个错误:

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

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 == [] 将返回 truecase不会匹配任何东西。在 Erlang 中,这将导致(抛出,确切地说是退出)case_clause 错误。所以你的实现总是会失败。

要解决此问题,您需要确保始终有与您的情况相匹配的内容,如下所示

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 是其他一些语言。最后它可以用函数子句编写,就像我之前展示的那样,但返回了这个合理的值。

<小时/>

编辑

返回值

如果你仔细看看我们的代码,现在我们只返回一个值;上次递归调用的那个(我称之为“理智”的那个)。如果您想考虑所有递归调用的所有计算,您需要以某种方式累积它们。为此,我们将使用 Acc 变量

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 中,并将此更新后的列表发送到下一级递归。最后,当我们的输入列表为空(我们处理了所有数据)时,我们只返回整个累加器。我们需要做的就是确保,当第一次调用 calculate 时,会使用空列表作为 Acc 来调用它。这可以通过新的(有点旧的)函数来完成

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

现在我们可以导出 calculate/4 并保持 calculate/5 私有(private)。

关于erlang - 当列表为空时检查而不是递归的情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26168545/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com