如何在Scala中处理空输入参数

时间:2012-11-29 22:00:46

标签: scala

我知道在Scala中,一个方法永远不应该返回null ...但是输入参数是什么?给出以下代码片段......

object MyObject {

    def myMethod(p: String): Option[String] = {
        if (p == null) throw new IllegalArgumentException("p is null.")
        ...
    }
}

...我检查p的方式是否正确?有什么建议吗?

4 个答案:

答案 0 :(得分:23)

惯例是Scala代码不使用空值(具有少量异常,在使用这些库函数时应立即修复)。

因此,Scala中的null表示某些内容出错(至少是PBCAK),因此您也可以抛出异常。这不是常规操作;这是严重搞砸的事情。无论何时遇到严重的搞砸,都要抓住例外。捕获IllegalArgumentException而不是NullPointerException不会增加额外信息。只留下原件。

如果代码来自Java,那么处理它的规范方法是将其包装在Option中,这会将null转换为None。那你甚至可能不需要抛出异常;只需返回None

def myMethod(p: String) = Option(p).map(_.toLowerCase)

如果在null时无法继续,那么您需要考虑信息性异常是否有用。 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。错误处理的惯例是预期输出为Right(whatever),而Left(whatever)表示出现问题。

答案 1 :(得分:6)

有几种方式,你的方式就是一种。

你也可以使用:

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")
}

答案 2 :(得分:0)

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()
}

多么可怕。

答案 3 :(得分:0)

我最喜欢的方法是:

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将为None,并且会修剪空格。