我正在阅读这本书 Thinking in Erlang .
在“图 10:案例示例”中有以下示例:
many(X) ->
case X of
[] ->
none;
[ _One ] ->
one;
[ _One, _Two ] ->
two;
[ _One, _Two , _Three | _Tail ] ->
many
end.
它说 :
If you are wondering why line 9 is not a match against [ _One, _Two | _Tail ], review the list matching rules for list tails at the end of the previous section.
但如果我真的匹配 [ _One, _Two | _Tail ] 一切仍然按预期工作。是书上有错误还是我弄错了?
最佳答案
我认为这可能不是错误。
的语义
[_One, _Two, _Three | _Tail]
是三个或更多元素的列表。
的语义
[_One, _Two | _Tail]
是两个或更多元素的列表。
自第三种模式
[ _One, _Two ]
已经使用 [_One, _Two | _Tail]
表示“两个元素的列表”的情况会有点多余。“一切都按预期工作”是有原因的。如果我们将第四个模式放在第三个模式之前,则给出:
many(X) ->
case X of
[] ->
none;
[_One] ->
one;
[_One, _Two | _Tail] -> %% Switched
many;
[_One, _Two] -> %% Switched
two
end.
那么一切都不会按预期工作。
Mod:many([a,b])
将产生 many
而不是预期的 two
.这是因为在计算“case”表达式时,X 依次与所有模式匹配。并且这个顺序是有保证的。 many
被退回是因为 [a,b]
匹配 [_One, _Two | _Tail]
首先,与 _Tail
正在 []
(空列表)。所以,即使
[ _One, _Two | _Tail ]
可以在您的情况下使用 [ _One, _Two , _Three | _Tail ]
被认为是一种很好的做法,以防您之后切换模式。
关于Erlang列表匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10884564/