使用Scala Option验证命令行参数

时间:2011-09-22 11:41:01

标签: scala validation

我正在使用Apache commons CLI在Scala实用程序应用程序中进行命令行解析。其中一个参数是数据库端口号(--port=),它覆盖默认的“5432”(对于PostgreSQL)。我正在尝试使用Option类来协助验证。这是我想出的代码。有没有更好的方法来进行验证?

val port = Option(commandLine.getOptionValue("port", "5432")) map {
  try {
    val value = Integer.parseInt(_)
    if (value < 1 || value > 65535) throw new NumberFormatException
    value
  } catch {
    case ex: NumberFormatException =>
      throw new
        IllegalArgumentException("the port argument must be a number between 1 and 65535")
  }
} get

端口号必须是介于1和65535之间的整数。

这样做会更好吗?为什么或为什么不呢?

val port = Option(commandLine.getOptionValue("port")) map {
  try {
    val value = Integer.parseInt(_)
    if (value < 1 || value > 65535) throw new NumberFormatException
    value
  } catch {
    case ex: NumberFormatException =>
      throw new
        IllegalArgumentException("the port argument must be a number between 1 and 65535")
  }
} getOrElse(5432)

2 个答案:

答案 0 :(得分:5)

我承认我不是百分百肯定,如果出现问题你想要抛出什么,或者5432是每个错误值的默认端口,但这就是我要做的事情:

def getPort(candidate: Option[String]) = candidate
   .map { _.toInt } // throws NumberFormatException
   .filter { v => v > 0 && v <= 65535 } // returns Option[Int]
   .getOrElse { throw new IllegalArgumentException("error message") } // return an Int or throws an exception

答案 1 :(得分:2)

我想这是我探索验证的好时机。

import scalaz._
import Scalaz._

val port = {
  def checkRange(port: Int): Validation[String, Int] = {
    if (port < 1 || port > 65535) "port not in [1-65535]".fail
    else port.success
  }
  commandLine.getOptionValue("port", "5432")
    .parseInt.flatMap(checkRange) match {
    case Failure(e) => throw new IllegalArgumentException(e.toString)
    case Success(port) => port
  }
}