我正在编写一个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'的关键字吗?
答案 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语句的值是ok
或do_nothing
,但case语句不是最后一个表达式,因此它的值不是函数第一个子句的返回值,并且因为case表达式的值没有绑定到变量,所以简单地丢弃该值。
第一个函数子句中的最后一个表达式实际上是printEven(Start+1, Stop)
,一旦递归到达序列的末尾并执行ok
1,该函数调用将最终返回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.