我能否强制Scala在不完整匹配时报错?

4

像这样的不完全匹配

(例如模糊匹配)
def foo[A](t: Seq[A]) = t match {
    Seq(x) => x
}

通常情况下(不总是,但通常是)在我编写的代码中会出现错误,在运行时会崩溃。Scala会发出警告,但在增量构建中,文件可能已经被编译,所以我会错过警告。

是否有一种方法,无论是全局还是局部,也许通过注释,来强制Scala将警告转换为错误?


我认为你的例子总是会发出错误... - som-snytt
3
我不确定你是否在询问-Xfatal-warnings选项。 - som-snytt
@som-snytt 啊,我不知道有关于 -Xfatal-warnings 的事情。如果没有办法针对这个特定的警告,那将是朝着正确方向迈出的一步。 - Owen
2
我在想为什么这不是一个编译器错误,即使没有使用“-Xfatal-warnings”。 - Dhruv Kapoor
@DhruvKapoor 可能是编译器有时无法评估完整性(涉及提取器时),而不完整的匹配可能是有用的(x sliding 2 map { case Seq(a, b) => })。 - Owen
2个回答

4
可以提供自定义的报告器来任意报告警告为错误(或相反),但是API目前是基于字符串的,因此它会过滤字符串消息而不是类型化的警告。
没有内置的方法来针对特定警告失败,但是-Xlint -Xfatal-warnings是升级警告的常用方式。
已经请求了警告抑制,但被认为是危险的。在致命警告的情况下,要求抑制被视为良性的警告。
如果您有残留的弃用问题,可以通过从弃用的方法调用它来抑制警告(在-Xfatal-warnings下会失败);如果该方法是本地的,则不会生成警告。
scala> @deprecated("","") def f = 8
f: Int

scala> f
<console>:9: warning: method f is deprecated: 
              f
              ^
scala> object A {
     | def a = {
     | @deprecated("","") def _f = f
     | _f
     | }}
defined object A

scala> A.a
res1: Int = 8

本地弃用技巧本身已经被弃用,但您仍然可以使用转发伴侣:
scala> @deprecated("","") def f = 8
f: Int

scala> f
warning: there was one deprecation warning; re-run with -deprecation for details
res0: Int = 8

scala> @deprecated("","") class C { def g = f }; object C extends C
defined class C
defined object C

scala> C.g
res1: Int = 8

从那时起,他们在本地警告抑制方面“屈服”,并添加了@nowarn以进行本地抑制和-Wconf以进行全局策略。 - som-snytt

0

考虑询问有关您的构建过程的问题。

  1. 在提交/检入代码之前,您应该进行完整的、清洁的构建(而不是增量构建),并立即运行单元测试。这样可以避免 SBT 或您的构建过程中可能存在的错误。当然,您需要监控结果以查找错误和警告。

  2. 您是否正在进行自动化、定期的构建/测试(即“持续集成”)?在此期间,您可以对如何处理警告(忽略或触发构建失败/警告)进行一些控制。

  3. 我没有看到从 scalac 命令行执行此操作的方法。如果所有其他方法都不能满足您的需求,那么请考虑最后的选择,但只有在适合您的构建工具时才这样做:为 scalac 创建一个包装脚本,也称为 scalac,它:

    • 调用真正的 scalac
    • 监视输出:当打印特定错误时返回错误,并可能删除目标类文件[从错误语句中捕获]以进一步强制执行。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接