我正在寻找一种通用的功能方式来将Scala String转换为任何数字类型。如果未能通过默认值,我需要。
例如,我需要从String
转换为Int
,但是如果String转换为Int转换失败。我需要在没有throws java.lang.NumberFormatException
的情况下传递默认值。我尝试了this方式,但没有得到我的想法,因为我需要它通用,并在异常情况下使用默认值
编辑:我更新了解决方案,以便从任何类型解析为任何类型。这使得解决方案基于所请求的问题更加通用。我认为你可以使用Scala功能方式来获得通用类型[T]
,但是你需要将它分成两部分。
首先实现从任何类型[U]
解析为任何类型[T]
的解析类型。 parseTypes
使用函数canBuildFrom
作为参数使用Scala函数方式。然后根据此函数的输出,您将检查它是否正确解析或是否有异常。此外,如果解析失败,您可以传递默认参数。
def parseTypes[T,U](str: U, canBuildFrom: U ⇒ T): Either[java.lang.NumberFormatException, T] =
Try(canBuildFrom(str)).map(Right(_)).getOrElse {
Left(new java.lang.NumberFormatException(str.toString))
}
def safeParse[T,U](attributeValue: U, canBuildFrom: U ⇒ T, defaultValue: T): T = {
parseTypes(attributeValue, canBuildFrom) match {
case Right(x) ⇒ x
case Left(x) ⇒ defaultValue
case _ ⇒ defaultValue
}
}
def safeParseDoubleToBigDecimal(attributeValue: Double): BigDecimal = safeParse[BigDecimal,Double](attributeValue, toBigDecimal, 0.0)
您可以使用它将String解析为Int,Double和Decimal,如下所示:
def safeParseStringToInt(attributeValue: String): Int = safeParse[Int,String](attributeValue, _.toInt, 0)
def safeParseStringToDouble(attributeValue: String): Double = safeParse[Double ,String](attributeValue, _.toDouble, 0.0)
def safeParseStringToBigDecimal(attributeValue: String): BigDecimal = safeParse[BigDecimal ,String](attributeValue, BigDecimal(_), 0.0)
// example of usage
val x:Int = safeParseStringToInt("123",0)
val y:Int = safeParseStringToInt("aaa",0)
对于类型类,这种事情实现得非常好:
trait ParseIt[T] {
protected def parse(s: String): T
def apply(s: String) = Try(parse(s)).toOption
}
implicit object ParseInt extends ParseIt[Int] {
protected def parse(s: String) = s.toInt
}
implicit object ParseDouble extends ParseIt[Double] {
protected def parse(s: String) = s.toDouble
}
// etc ...
def parse[T : ParseIt](s: String, orElse: => T) =
implicitly[ParseIt[T]](s).getOrElse(orElse)
val n: Int = parse("123", 0)
val d: Double = parse("123", 0.0)