在Erlang中,有没有办法创建一个空函数?

时间:2009-07-14 17:11:31

标签: function erlang

我正在编写一个Erlang函数,它会将每个偶数打印到给定参数。

到目前为止,我已经用这样的警卫编写了这个函数:

printEven(I,N) when I < N ->
  if
    I rem 2 == 0 -> io:format("~p~n",[I]), printEven(I+1,N);
    I rem 2 == 1 -> printEven(I+1,N)
  end;
printEven(I,N) ->
   io:format("Done").

我真的很想让最后一个案例自动退出,而不必在函数中打印任何内容。我试过删除它,但随后发生错误,因为递归完成后,会抛出错误。

我该怎么做?在erlang中有类似'pass'或'yield'的关键字吗?

6 个答案:

答案 0 :(得分:11)

好的,首先定义函数:

printEven(I,N) when I >= N -> ok;
printEven(I,N)             -> 
   if
    I rem 2 == 0 -> io:format("~p~n",[I]), printEven(I+1,N);
    I rem 2 == 1 -> printEven(I+1,N)
  end.

Erlang是一种函数式编程语言,并且(根据定义)函数“具有”一个值,因此您将获得“某些东西”。按照惯例,你在完成一个用于副作用的函数时得到的东西是原子'ok',这是最好在这里使用。

如果需要,您可以'静默地丢弃'返回值。当你通过模式匹配'do not care'变量(下划线)来调用函数时,你可以这样做:

_ = printEven(3,9),

或通过调用没有模式匹配的函数:

printEven(3,9),

但是,在调用函数时,最好通过模式匹配来检查返回值:

ok = printEven(3,9),

这是一个非常好的习惯,因为你将使用很多库函数返回错误代码,你可以从他们的规范中看到:

@spec funky(X) -> [ok | {error, bad_op} | {error, wig_out}]

如果funky有副作用你想通过模式匹配调用它已经失败 现在 ,所以它会在这里崩溃,现在如果funky失败了:

ok = funky(99),

如果你将它与'_'相匹配或忽略返回值,那么当你的mojo希望时髦完成他的演绎时它将会崩溃268行,然后它 很多 更难找到。

这是一个快乐的路径编程,这是Erlang中完成的事情。 “让它崩溃”是座右铭。如果你是Erlang的新手,你会发现这非常令人不安 - 就像赤身裸体走路一样。别担心拥抱它,这是一件好事。它导致许多代码“没有被写入”。

(您还应养成将结束递归的子句作为此处所示的顶级子句的习惯 - 这使得在阅读代码 sooo 时更容易你有一个多子句功能。)

答案 1 :(得分:4)

只返回一个原子。

printEven(I,N) - &gt;完成。

应该这样做。

答案 2 :(得分:2)

即使在guard子句中,您也可以将测试结合起来。我也更喜欢完成原子技巧 - 它在你的代码中显示它是将停止“递归”的函数子句。

printEven(I, N) when I<N, I rem 2 == 0 ->
    io:format("~p is even~n", [I]),
    printEven(I+1, N);
printEven(I,N) when I<N ->
    printEven(I+1, N);
printEven(I,N) ->
    done.

答案 3 :(得分:1)

我认为该关键字为“ok

答案 4 :(得分:0)

printEven(Start, Stop) when Start =< Stop ->
    case Start rem 2 of
        0 -> io:format("~p~n", [Start]);  %returns ok
        _ -> do_nothing
    end,  
    printEven(Start+1, Stop);
printEven(Start, Stop) when Start > Stop ->
    ok.

case语句的值是okdo_nothing,但case语句不是最后一个表达式,因此它的值不是函数第一个子句的返回值,并且因为case表达式的值没有绑定到变量,所以简单地丢弃该值。

第一个函数子句中的最后一个表达式实际上是printEven(Start+1, Stop),一旦递归到达序列的末尾并执行ok printEven(Start, Stop) when Start > Stop -> ok; p>

printEven(1, 3) => ?
                   | 
                   V
             printEven(2, 3) => ?
                                | --side effect: output 2
                                V
                         printEven(3, 3) => ?
                                            |
                                            V 
                                      printEven(4, 3) => ok 

填写每个函数的返回值,调用链给出:

printEven(1, 3) =>  ok
                    ^ 
                    |
              printEven(2, 3) => ok
                                 ^ 
                                 |
                         printEven(3, 3) => ok
                                            ^
                                            |
                                      printEven(4, 3) => ok 

答案 5 :(得分:-1)

这样就可以了:

printEven(I,N) -> ok.