我有很多这样的功能:
// Convert a string to integer, defaulting to 0 if it fails
def safeToInt(s: String): Int = try {
s.toInt
} catch {
case _: NumberFormatException => 0
}
// Convert a string to long, defaulting to 0 if it fails
def safeToLong(s: String): Long = try {
s.toLong
} catch {
case _: NumberFormatException => 0
}
// Convert a string to double, defaulting to 0 if it fails
def safeToDouble(s: String): Double = try {
s.toDouble
} catch {
case _: NumberFormatException => 0
}
有什么方法可以让这些更干净?除了一行之外,它们基本上都做同样的事情。
答案 0 :(得分:4)
您可以利用Numeric
来避免重复归零。
import scala.util.Try
def safeToNumeric[A: Numeric](f: String => A)(s: String): A =
Try(f(s)).getOrElse(implicitly[Numeric[A]].zero)
val safeToInt = safeToNumeric(_.toInt)(_)
val safeToLong = safeToNumeric(_.toLong)(_)
val safeToDouble = safeToNumeric(_.toDouble)(_)
safeToInt("4") // 4
safeToDouble("a") // 0.0
不幸的是Numeric
也没有给你解析方法,但你可以自己创建合适的类型类......
case class Parser[A](parse : String => A)
implicit val intParser = Parser(_.toInt)
implicit val longParser = Parser(_.toLong)
implicit val doubleParser = Parser(_.toDouble)
...然后你可以编写一个适用于所有类型的方法。
def safeTo[A: Parser : Numeric](s: String): A =
Try(implicitly[Parser[A]].parse(s))
.getOrElse(implicitly[Numeric[A]].zero)
safeTo[Int]("4") // 4
safeTo[Double]("a") // 0.0
答案 1 :(得分:2)
您可以使用scala.util.Try
import util.Try
// Convert a string to integer, defaulting to 0 if it fails
def safeToInt(s: String): Int = Try(s.toInt).getOrElse(0)
// Convert a string to long, defaulting to 0 if it fails
def safeToLong(s: String): Long = Try(s.toLong).getOrElse(0L)
// Convert a string to double, defaulting to 0 if it fails
def safeToDouble(s: String): Double = Try(s.toDouble).getOrElse(0.0)
答案 2 :(得分:1)
虽然克里斯·马丁的答案可能是最复杂的,但却相当复杂。你可以封装"尝试一些东西,或者让我得到默认的"通过使用返回函数的函数。
import scala.util.Try
def safeConverter[A](convert: String => A, default: A) = { input: String =>
Try(convert(input)).getOrElse(default)
}
val safeToInt = safeConverter(_.toInt, 0)
val safeToLong = safeConverter(_.toLong, 0L)
val safeToDouble = safeConverter(_.toDouble, 0.0)
safeToInt("334") // Returns 334
safeToInt("this is not a number") // Returns 0
converter
返回一个函数,该函数在抛出异常的情况下执行String的转换。
您可以将此converter
用于任何可能引发异常的转化,而不只是数字值。