首页 > 解决方案 > 在scala中警告或避免整数除法(导致截断)

问题描述

考虑

 1 / 2

或者

 val x: Int = ..
 val n: Int = ..

 x / n

这两个都等于 .. 0 .. 因为整数除法会导致截断。

另外:(这是我的典型用例):

val averageListSize =  myLists.map(_.length).sum()/myLists.length

当它发生在长时间计算的中间时,这让我痛苦了几次:第一个冲动是检查引入了哪些逻辑错误。只有经过一段时间的调试和挠头,真正的罪魁祸首才会出现。

有什么方法可以更清楚地揭示这种行为 - 例如警告或某些(我不知道的)语言设置或构造,它们会提醒或避免这种间歇性情况?

标签: scala

解决方案


据我所知,Scala 编译器似乎没有提供可以让您发出警告的警告标志(此处的文档)。

但是,如果您觉得值得付出努力,您可以做的是使用Scalafix并编写您自己的自定义规则来检测整数除法并报告有关它的警告。

以下是可以检测整数文字上的整数除法的规则的简短示例:

import scalafix.lint.{Diagnostic, LintSeverity}
import scalafix.patch.Patch
import scalafix.v1.{SemanticDocument, SemanticRule}

import scala.meta.inputs.Position
import scala.meta.{Lit, Term}

class IntDivision extends SemanticRule("IntDivision") {

  override def fix(implicit doc: SemanticDocument): Patch =
    doc.tree.collect({
      case term @ Term.ApplyInfix((_: Lit.Int, Term.Name("/"), Nil, _: List[Lit.Int])) =>
        Patch.lint(new Diagnostic {
          override final val severity: LintSeverity = LintSeverity.Warning
          override final val message: String = "Integer division"
          override final val position: Position = term.pos
        })
    }).asPatch

}

在以下代码上运行时:

object Main {
  def main(args: Array[String]): Unit = {
    println(1 / 2)
  }
}

Scalafix 将产生以下警告:

[warn] /path/to/Main.scala:3:13: warning: [IntDivision] Integer division
[warn]     println(1 / 2)
[warn]             ^^^^^

推荐阅读