【发布时间】:2014-07-11 18:17:55
【问题描述】:
我正在尝试从 xml 字段中获取一个数字
...
<Quantity>12</Quantity>
...
通过
Some((recipe \ "Main" \ "Quantity").text.toInt)
但有时 xml 中可能没有值。文本将是 "",这会引发 java.lang.NumberFormatException。
获取 Int 或 None 的干净方法是什么?
【问题讨论】:
我正在尝试从 xml 字段中获取一个数字
...
<Quantity>12</Quantity>
...
通过
Some((recipe \ "Main" \ "Quantity").text.toInt)
但有时 xml 中可能没有值。文本将是 "",这会引发 java.lang.NumberFormatException。
获取 Int 或 None 的干净方法是什么?
【问题讨论】:
Scala 2.13介绍String::toIntOption:
"5".toIntOption // Option[Int] = Some(5)
"abc".toIntOption // Option[Int] = None
"abc".toIntOption.getOrElse(-1) // Int = -1
【讨论】:
这是另一种不需要编写自己的函数的方法,也可以用于提升到Either。
scala> import util.control.Exception._
import util.control.Exception._
scala> allCatch.opt { "42".toInt }
res0: Option[Int] = Some(42)
scala> allCatch.opt { "answer".toInt }
res1: Option[Int] = None
scala> allCatch.either { "42".toInt }
res3: scala.util.Either[Throwable,Int] = Right(42)
(关于主题的nice blog post。)
【讨论】:
在接受的答案之后,更多关于用法的旁注。 import scala.util.Try之后,考虑
implicit class RichOptionConvert(val s: String) extends AnyVal {
def toOptInt() = Try (s.toInt) toOption
}
或类似但更详细的形式,仅解决转换为整数值的相关异常,在import java.lang.NumberFormatException之后,
implicit class RichOptionConvert(val s: String) extends AnyVal {
def toOptInt() =
try {
Some(s.toInt)
} catch {
case e: NumberFormatException => None
}
}
因此,
"123".toOptInt
res: Option[Int] = Some(123)
Array(4,5,6).mkString.toOptInt
res: Option[Int] = Some(456)
"nan".toInt
res: Option[Int] = None
【讨论】:
"nan".toInt 是"nan".toOptInt?
scala> import scala.util.Try
import scala.util.Try
scala> def tryToInt( s: String ) = Try(s.toInt).toOption
tryToInt: (s: String)Option[Int]
scala> tryToInt("123")
res0: Option[Int] = Some(123)
scala> tryToInt("")
res1: Option[Int] = None
【讨论】:
if (s.isEmpty) None else Try(s.toInt).toOption。