如何find一个Scalastring是否可parsing为Double或不?

假设我在scala中有一个string,我想试图parsing一个双精度。

我知道,我可以调用toDouble ,然后捕获Java的NUM格式exception,如果失败,但有没有更干净的方法来做到这一点? 例如,如果有一个返回Option[Double]parseDouble函数,这将有资格。

我不想把它放在我自己的代码中,如果它已经存在于标准库中,我只是在错误的地方寻找它。

感谢您的任何帮助,您可以提供。

要不就

 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) 

Scalaz在String上提供了一个扩展方法parseDouble ,它给出了Validation[NumberFormatException, Double]types的值。

 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 
 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 

你可以尝试使用util.control.Exception.catching ,它返回一个Eithertypes。

所以使用下面的方法返回一个包装NumberFormatException的Left或一个包装Double的Right

 import util.control.Exception._ catching(classOf[NumberFormatException]) either "12.W3".toDouble 

这不仅仅是在Scala中,甚至在基本的Java中也是如此。

尽pipe这里有一段代码,但没有例外

 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") 

不幸的是,这不在标准库中。 以下是我使用的:

 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) 

我通常会去“就地”尝试:

 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中进行进一步计算,并且任何exception都将投影到Failure(ex)中。 AFAIK这是处理一系列不可靠操作的惯用方式。