为什么在这个功能中使用“when”?

问题描述:

有一个在“Erlang编程”这个指数函数:为什么在这个功能中使用“when”?

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

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

+0

不知道Erlang(只有OCaml)所以我会留下它作为评论:哪种模式会匹配N == - 1我的猜测是第二个(如果它不是守卫) – 2010-08-08 15:02:28

+0

符文FS ,这是我的第一个想法,但索引(-1,[1,2,3])导致“**异常错误:没有函数子句匹配测试:index(-1,[1,2,3])” – 2010-08-08 15:07:16

+0

但是如果你移除了后卫不符合那么? – 2010-08-08 15:33:50

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

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

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

when子句防止负指数(编辑:查看对原始问题的评论;)。

它还给出了更明确的代码,就像您明确说出此子句有效时那样,而不仅仅是默认情况下。是的,我知道在一些(很多)情况下,这是不可能的,因为测试可能变得非常复杂,或者您需要某种形式的默认情况。但不在这里。