我想知道人们如何处理SML / NJ编译器中的非穷举匹配警告。例如,我可以定义数据类型
datatype DT = FOO of int | BAR of string
然后有一个我知道只需要FOOs的功能
fun baz (FOO n) = n + 1
编译器会发出警告
stdIn:1.5-1.24 Warning: match nonexhaustive FOO n => ... val baz = fn : DT -> int
我不想看到我故意做的不完整匹配的警告,因为那时我必须扫描输出以找到可能实际上是错误的警告。我可以写这个函数
fun baz (FOO n) = n + 1
| baz _ = raise Fail "baz"
但这会使代码混乱。在这种情况下人们通常会做些什么?
答案 0 :(得分:3)
您可以设置以下编译器标志来配置非详尽匹配警告的警告级别:
如果这两个都设置为false,则不会生成警告。不幸的是,这将关闭此错误的所有实例的警告,这可能不是您想要的,因为它将删除此安全措施。
(注意:您只需在代码中将这些设置为false)
可以找到更多信息here。第46项具体描述了你的警告。
答案 1 :(得分:3)
正如丹尼尔所说,你可以关闭警告,但我不建议这样做。
最好能够调整数据类型,以便函数能够在允许的整个值范围内运行。第二个最好的方法是继续使用错误“混乱”代码,使其明确发生了什么(并允许更有意义的运行时错误)。
答案 2 :(得分:2)
您必须覆盖所有案例,以便您已决定该函数如何处理其整个域,或者使用警告。最后一种方法是首先修改你通过函数提供的值,以便在调用者中完成解构。
答案 3 :(得分:1)
我认为如果你这么做很多,你需要重新思考一下你的数据类型。如果它们不是同一种对象,为什么要将Foo和Baz组合在一个数据类型中?如果它们是构造同一个对象的不同方式,那么你会期望在Foo上运行的函数也能够在Baz上做一些合理的事情。如果你有一个带有构造函数Car和Bike的类型的Vehicle,但你只想在Cars上做一些操作,如果你的代码很大,那么正确的做法可能是将Car的定义分开并改变你使用的所有地方车辆,但期望只有汽车直接使用汽车。
答案 4 :(得分:1)
与其他答案一样,更改数据类型以产生详尽的匹配更为清晰。在这种情况下,您可以更改DT
类型,也可以更改baz
的返回类型。例如:
datatype DT = FOO of int | BAR of string
fun baz (FOO n) = SOME (n + 1)
| baz _ = NONE
然后baz
的类型为val baz = fn : DT -> int option
,您无需担心处理baz
引发的错误。