Scala:将字符串转换为Int或None

时间:2014-05-22 15:40:53

标签: scala casting option

我想从xml字段中获取一个数字

...
<Quantity>12</Quantity>
...

经由

Some((recipe \ "Main" \ "Quantity").text.toInt)

但有时候xml中可能没有值。该文本将为"",并抛出java.lang.NumberFormatException。

获得Int或None的干净方法是什么?

4 个答案:

答案 0 :(得分:63)

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

答案 1 :(得分:10)

更多关于接受答案后使用情况的附注。在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

因此,

{{1}}

答案 2 :(得分:5)

这是另一种方法,不需要编写自己的函数,也可以用来升级到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。)

答案 3 :(得分:4)

Scala 2.13引入了String::toIntOption

"5".toIntOption                 // Option[Int] = Some(5)
"abc".toIntOption               // Option[Int] = None
"abc".toIntOption.getOrElse(-1) // Int = -1