7

《Erlang Programming》中有这个索引函数:

index(0, [X|_]) -> X;
index(N, [_|Xs]) when N>0 -> index(N-1, Xs)

由于模式匹配,守卫“当N>0”不是多余的吗?调用 index(0, List) 将永远不会在第二个子句中结束,因此 N 将始终 > 0。或者我在这里完全错了吗?

4

3 回答 3

12

该函数在 N>=0 时正常工作。如果没有警卫,对于 N<0 它将遍历整个列表:

索引(-2,[1,2,3]) -> 索引(-3,[2,3]) -> ... -> 索引(-5,[]) -> 错误。

这不是一个大问题,只是你可能会遇到一个令人困惑的异常。在具有无限列表的语言(Haskell、Ocaml)中,忘记那个守卫可能会导致无限循环:index(-1, [0,0,0..])。

于 2010-08-08T15:35:00.420 回答
6

when 子句防止负索引(编辑:请参阅原始问题的评论;)。

于 2010-08-08T15:23:11.580 回答
5

当此子句有效时,它还会提供更清晰的代码,而不仅仅是默认情况下。是的,我知道在某些(许多)情况下,这是不可能正确执行的,因为测试可能变得非常复杂,或者您需要某种形式的默认情况。但不是在这里。

于 2010-08-09T01:00:57.177 回答