为什么“当”是“当”?在这个函数中使用?
《Erlang编程》里有这个索引函数:
index(0, [X|_]) -> X;
index(N, [_|Xs]) when N>0 -> index(N-1, Xs)
难道因为模式匹配,“when N>0”这个守卫是多余的吗?调用 index(0, List) 永远不会在第二个子句中结束,因此 N 将始终 > 0.或者我完全错了?
There is this index function in "Erlang Programming":
index(0, [X|_]) -> X;
index(N, [_|Xs]) when N>0 -> index(N-1, Xs)
Isn't the guard "when N>0" superfluous because of the pattern matching? Calling index(0, List) will never end up in the second clause so N will always be > 0. Or am I totally wrong here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
当 N>=0 时,该函数可以正常工作。如果没有保护,对于 N<0,它将遍历整个列表:
index(-2,[1,2,3]) ->索引(-3,[2,3]) -> ...->索引(-5,[]) ->错误。
这不是一个大问题,只是您可能会遇到令人困惑的异常。在具有无限列表的语言(Haskell、Ocaml)中,忘记该守卫可能会导致无限循环:index(-1, [0,0,0..])。
The function works correctly for N>=0. Without a guard, for N<0 it would traverse the whole list:
index(-2,[1,2,3]) -> index(-3,[2,3]) -> ... -> index(-5,[]) -> error.
That isn't a large problem, only you might get a confusing exception. In languages with infinite lists (Haskell, Ocaml), forgetting about that guard might lead to infinite loop: index(-1, [0,0,0..]).
when 子句防止负索引(编辑:请参阅对原始问题的评论;)。
The when clause guards against negative indices (edit: see comments to original question ;).
当您明确指出该子句何时有效时,它还提供了更清晰的代码,而不仅仅是默认情况下。是的,我知道在某些(许多)情况下这是不可能正确执行的,因为测试可能会变得非常复杂或者您需要某种形式的默认情况。但不在这里。
It also gives clearer code as you explicitly say when this clause is valid, not just by default. Yes, I know that in some (many) cases this is not possible to do properly as the test may become very complex or that you want some form of default case. But not here.