【问题标题】:Scala: convert string to Int or NoneScala:将字符串转换为 Int 或 None
【发布时间】:2014-07-11 18:17:55
【问题描述】:

我正在尝试从 xml 字段中获取一个数字

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

通过

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

但有时 xml 中可能没有值。文本将是 "",这会引发 java.lang.NumberFormatException。

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

【问题讨论】:

标签: scala casting option


【解决方案1】:

Scala 2.13介绍String::toIntOption

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

【讨论】:

    【解决方案2】:

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

    在接受的答案之后,更多关于用法的旁注。 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
    【解决方案4】:
    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
    猜你喜欢
    • 2013-03-02
    • 1970-01-01
    • 1970-01-01
    • 2012-07-26
    • 1970-01-01
    • 2020-08-27
    • 1970-01-01
    • 2011-10-02
    相关资源
    最近更新 更多