我知道在 Scala 中,一个方法永远不应该返回null
……但是输入参数呢?鉴于以下代码片段...
object MyObject {
def myMethod(p: String): Option[String] = {
if (p == null) throw new IllegalArgumentException("p is null.")
...
}
}
...我检查的方式是否p
正确?有什么建议吗?
我知道在 Scala 中,一个方法永远不应该返回null
……但是输入参数呢?鉴于以下代码片段...
object MyObject {
def myMethod(p: String): Option[String] = {
if (p == null) throw new IllegalArgumentException("p is null.")
...
}
}
...我检查的方式是否p
正确?有什么建议吗?
约定是 Scala 代码不使用空值(有少量异常,在使用这些库函数时应该立即修复)。
因此,Scala 中的 null 表示出现问题(至少是PBCAK),因此您不妨抛出异常。这不是常规操作;这是严重搞砸的事情。在遇到严重错误的地方捕获异常。捕捉 anIllegalArgumentException
而不是 aNullPointerException
不会增加额外的信息。只留下原件。
如果代码来自 Java,处理它的规范方法是将其包装在 中Option
,这将转换null
为None
. 那么你可能甚至不需要抛出异常;只返回一个None
.
def myMethod(p: String) = Option(p).map(_.toLowerCase)
如果您在它为空时无法继续,那么您需要考虑信息异常是否会有所帮助。 Option(p).orElse(throw new IllegalArgumentException("Null!"))
是表达异常抛出情绪的一种紧凑方式。
在 Scala 2.10 中,您还可以包装一些东西,scala.util.Try(...)
这些东西会自动为您捕获和打包异常。如果您想要一个打包的异常而不是抛出一个异常,这就是要走的路。(并使用Try
而不是Option
。)
import scala.util.Try
def myMethod(p: String) = Try(p.toLowerCase)
最后,对于替代结果的更一般处理,请使用Either
. 错误处理的约定是预期的输出是 a Right(whatever)
,而Left(whatever)
表示出现了问题。
有几种方法,你的方法是一种。
您还可以使用:
require(p != null, "p is null.")
或者“更实用”的方式是使用Option
:
def myMethod(p: String): Option[String] = {
// no exception
for {
pp <- Option(p)
} yield p + " foo bar"
}
编辑:
或者,如果您希望没有抛出异常的错误,您可以使用Either
:
def myMethod(p: String): Either[Exception, String] = {
if(p == null) Left(new IllegalArgumentException("p is null."))
else Right(p + "foo bar")
}
Scala 习语本质上是“永远不要使用空值”。因此,除非您正在编写一个需要适应肮脏的 Java 用户的 API,否则我不会担心它。否则,您将最终为您编写的每个方法的每个参数插入此样板检查。
你漂亮的单行方法
def square(x: String): String = math.pow(x.toInt, 2).toInt.toString
会变成一些尴尬的东西
def square(x: String): String =
if (x == null) throw new NullPointerException()
math.pow(x.toInt, 2).toInt.toString
}
或者
def square(x: String): String = Option(x) match {
case Some(x) => math.pow(x.toInt, 2).toInt.toString
case None => throw new NullPointerException()
}
多么可怕。
我最喜欢的方法是:
object HandlingInputValidation {
def main(args: Array[String]) = {
println("A1: " + handleInput("Correct ") + " END")
println("A2: " + handleInput("Correct") + " END")
println("A3: " + handleInput("") + " END")
println("A4: " + handleInput(" ") + " END")
println("A5: " + handleInput(null) + " END")
}
def handleInput(data: String): Option[String] = {
Option(data).map(_.trim.toLowerCase)
}
}
在这种情况下,null
will be None
,并且空格将被修剪。