3
# let [x;y;z] = [1;2;3];;
Warning P: this pattern-matching is not exhaustive.
Here is an example of a value that is not matched:
[]
val x : int = 1
val y : int = 2
val z : int = 3
# x;;
- : int = 1
# y;;
- : int = 2
# z;;
- : int = 3

似乎值声明工作得很好,警告实际上是想告诉什么?

4

2 回答 2

5

该模式[x; y; z]与其类型的所有可能值都不匹配。一般来说,您希望避免这样的模式——这意味着在某些情况下您的代码会失败。在这种特殊情况下(如果您从不更改代码)没有问题,因为模式与常量值匹配。但是编译器无论如何都会警告你,以防万一。也许它认为您以后可能会更改常量列表。

我不得不说,如果有一种方法可以在这种情况下禁用警告,那就太好了。

写这个的惯用方式(没有警告)是:

let x, y, z = 1, 2, 3

在这种情况下,模式 ( x, y, z)确实匹配其类型的所有可能值。

于 2013-01-27T14:53:56.500 回答
0

基本上,任何表达式绑定都会在编译时转换为模式匹配,因为可以在绑定符号的左侧写入模式=。所以这就像你写的一样:

let x,y,z = 
    let v =  [1;2;3] in
    match v with
      | [x;y;z] -> x,y,z

这有点令人费解,但是经过类型检查的代码可能与上面的[1]有点相似。在此设置中,您可能会更好地看到,无论您使用简单的绑定表达式还是完整的match ... with表达式,模式匹配机制都是相同的。在这两种情况下,如果存在模式匹配遗漏的情况,类型检查器将从表达式的类型推断,并警告您。对于list模式匹配,该值确实[]是一种可能性。


[1]:我说“可以”,因为我相信实际上match ... with 句法形式也被转换为另一种形式,这可能更接近于function形式(即function [x;y;z] -> ...在你的情况下)。

于 2013-01-28T01:34:32.617 回答