《Erlang Programming》中有这个索引函数:
index(0, [X|_]) -> X;
index(N, [_|Xs]) when N>0 -> index(N-1, Xs)
由于模式匹配,守卫“当N>0”不是多余的吗?调用 index(0, List) 将永远不会在第二个子句中结束,因此 N 将始终 > 0。或者我在这里完全错了吗?
《Erlang Programming》中有这个索引函数:
index(0, [X|_]) -> X;
index(N, [_|Xs]) when N>0 -> index(N-1, Xs)
由于模式匹配,守卫“当N>0”不是多余的吗?调用 index(0, List) 将永远不会在第二个子句中结束,因此 N 将始终 > 0。或者我在这里完全错了吗?
该函数在 N>=0 时正常工作。如果没有警卫,对于 N<0 它将遍历整个列表:
索引(-2,[1,2,3]) -> 索引(-3,[2,3]) -> ... -> 索引(-5,[]) -> 错误。
这不是一个大问题,只是你可能会遇到一个令人困惑的异常。在具有无限列表的语言(Haskell、Ocaml)中,忘记那个守卫可能会导致无限循环:index(-1, [0,0,0..])。
when 子句防止负索引(编辑:请参阅原始问题的评论;)。
当此子句有效时,它还会提供更清晰的代码,而不仅仅是默认情况下。是的,我知道在某些(许多)情况下,这是不可能正确执行的,因为测试可能变得非常复杂,或者您需要某种形式的默认情况。但不是在这里。