假设我在scala中有一个字符串,我想尝试解析它中的双精度数。
我知道,我可以调用toDouble
,然后在失败的情况下捕获java num格式异常,但是有更简洁的方法吗?例如,如果有parseDouble
函数返回Option[Double]
,那么这将符合条件。
如果它已经存在于标准库中,我不想把它放在我自己的代码中,我只是在错误的地方寻找它。
感谢您提供的任何帮助。
答案 0 :(得分:52)
或者只是
def parseDouble(s: String) = try { Some(s.toDouble) } catch { case _ => None }
花哨版:
case class ParseOp[T](op: String => T)
implicit val popDouble = ParseOp[Double](_.toDouble)
implicit val popInt = ParseOp[Int](_.toInt)
// etc.
def parse[T: ParseOp](s: String) = try { Some(implicitly[ParseOp[T]].op(s)) }
catch {case _ => None}
scala> parse[Double]("1.23")
res13: Option[Double] = Some(1.23)
scala> parse[Int]("1.23")
res14: Option[Int] = None
scala> parse[Int]("1")
res15: Option[Int] = Some(1)
答案 1 :(得分:31)
Scalaz在parseDouble
上提供了一种扩展方法String
,其值为Validation[NumberFormatException, Double]
。
scala> "34.5".parseDouble
res34: scalaz.Validation[NumberFormatException,Double] = Success(34.5)
scala> "34.bad".parseDouble
res35: scalaz.Validation[NumberFormatException,Double] = Failure(java.lang.NumberFormatException: For input string: "34.bad")
如果需要,您可以将其转换为Option
。
scala> "34.bad".parseDouble.toOption
res36: Option[Double] = None
答案 2 :(得分:19)
scala> import scala.util.Try
import scala.util.Try
scala> def parseDouble(s: String): Option[Double] = Try { s.toDouble }.toOption
parseDouble: (s: String)Option[Double]
scala> parseDouble("3.14")
res0: Option[Double] = Some(3.14)
scala> parseDouble("hello")
res1: Option[Double] = None
答案 3 :(得分:10)
您可以尝试使用返回util.control.Exception.catching
类型的Either
。
因此,使用以下内容返回左包装NumberFormatException
或右包装Double
import util.control.Exception._
catching(classOf[NumberFormatException]) either "12.W3".toDouble
答案 4 :(得分:6)
不仅在Scala中,甚至在基本的Java中也没有这样的东西。
这是一个代码无异常,但是:
def parseDouble(s: String)(implicit nf: NumberFormat) = {
val pp = new ParsePosition(0)
val d = nf.parse(s, pp)
if (pp.getErrorIndex == -1) Some(d.doubleValue) else None
}
用法:
implicit val formatter = NumberFormat.getInstance(Locale.ENGLISH)
Console println parseDouble("184.33")
Console println parseDouble("hello, world")
答案 5 :(得分:6)
不幸的是,这不在标准库中。这是我使用的:
class SafeParsePrimitive(s: String) {
private def nfe[T](t: => T) = {
try { Some(t) }
catch { case nfe: NumberFormatException => None }
}
def booleanOption = s.toLowerCase match {
case "yes" | "true" => Some(true)
case "no" | "false" => Some(false)
case _ => None
}
def byteOption = nfe(s.toByte)
def doubleOption = nfe(s.toDouble)
def floatOption = nfe(s.toFloat)
def hexOption = nfe(java.lang.Integer.valueOf(s,16))
def hexLongOption = nfe(java.lang.Long.valueOf(s,16))
def intOption = nfe(s.toInt)
def longOption = nfe(s.toLong)
def shortOption = nfe(s.toShort)
}
implicit def string_parses_safely(s: String) = new SafeParsePrimitive(s)
答案 6 :(得分:3)
Scala 2.13
引入了String::toDoubleOption
:
"5.7".toDoubleOption // Option[Double] = Some(5.7)
"abc".toDoubleOption // Option[Double] = None
"abc".toDoubleOption.getOrElse(-1d) // Double = -1.0
答案 7 :(得分:1)
我通常会选择"到位"尝试:
def strTimesTen (s: String) = for (d <- Try(s.toDouble)) yield d * 10
strTimesTen("0.1") match {
Success(d) => println( s"It is $d" )
Failure(ex) => println( "I've asked for a number!" )
}
请注意,您可以在for中进行进一步计算,任何异常都会投射到Failure(ex)中。 AFAIK这是处理一系列不可靠操作的惯用方法。