我在github上有一个由codacy分析的项目。分析建议"避免对以下代码行使用null" :
def doSomethingWithPath(path:Path) = {
require(path != null, "Path should not be null") //<-to avoid
...
}
修复它最简单的scala惯用法是什么?
答案 0 :(得分:6)
如果 minDateFilter = new Date(date).getTime();
实际上 path
,这可能是最简单的。
null
答案 1 :(得分:5)
我会保持原样。你并不是真的在这里使用null,只是防范它。替代方法可能是完全删除该行,并决定根本不处理null。忽略null的可能性在一个构建良好的代码库中可能没什么问题,因为它无论如何都不应该出现而null将是一个bug,但是一个简单的保护来捕获它可以防止出现更多微妙的错误以防万一实际上发生了错误和null。
答案 2 :(得分:4)
最惯用的方法是避免要求(不确定,但我知道它可以抛出异常 - Scala强烈建议反对)
def doSomethingWithPath(path:Path): Option[stuff] = { // will return an option of the type you were returning previously.
Option(path).map { notNullPath =>
...
}
}
现在可能的null
案例将返回给调用者,它可以/将传播返回的Option,直到知道如何正确处理它的层。
注意:处理null case的最佳位置可能在你的函数内部。在这种情况下,你应该做类似
的事情
Option(path).map { notNullPath =>
...
}.getOrElse(/* take care of null case */)
如果你想保留require
,那么answer by jwvh也是我的选择
答案 3 :(得分:2)
无需在path
中明确检查null或包裹Option
。
你可以这样做:
path match {
case p: String => Option(doSomethingWith(p))
case _ => None //if path is null this will be returned
}
这将返回Option
,这可能不是您想要的,但在这种情况下,而不是生成None
,引发异常。 require
无论如何都会在你的例子中引发一个异常,所以如果这是你的调用者所期望的,那就明确地做了。
答案 4 :(得分:0)
禁止使用null是一种最佳做法。 This article explains why和Guava:即席错误处理,模糊语义,慢速失败等。
编写需求来自于在不满足调用方法的前提条件时快速和清理失败的需要。问题在于,它只是用@puhlen解释的另一个例外来取代NPE(更具描述性)。
在理想世界中,Rails.env
将与path:Path
相同,并且不需要对对象的存在进行测试。问题是scala(与其他语言一样多)允许null打破纯面向对象的方法。
java / scala编译器应该强制Optional类型作为管理null的唯一代码并强制在键入系统中存在null。在这种情况下,任何null的使用都可以被视为编译错误。我不知道这是否完全可行。
由于没有语言/编译器级别的默认行为,因此库之间的阻抗不匹配。
使用Predef2定义我自己的类,并使用最少的样板逻辑。我仍然只会得到一个&#34;避免使用null&#34;或使用guava Preconditions.checkNotNull
number:Int