scala - 有什么方法可以干掉这些用默认值转换数字的函数?

标签 scala dry

我有很多这样的功能:

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

有什么办法可以让这些更干净?除了一行之外,它们基本上都做同样的事情。

最佳答案

您可以利用 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

关于scala - 有什么方法可以干掉这些用默认值转换数字的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24380061/

相关文章:

java - builder 模式中的重复

scala - hiveql删除重复项,包括具有重复项的记录

scala - 用什么NoSQL数据库替代MySQL?

python - 使用额外的属性和方法指定 django 模型字段选择的好 Pythonic 方法

c# - 如果两个功能几乎相同,如何遵守 DRY 原则?

ruby-on-rails - Rails - Cucumber 场景中的 DRY。什么是良好的平衡?

scala - 排序时间戳的scala arrayBuffer

scala - 仅使用 IO monad 中的值,无需先行 IO 操作

java - 为什么当需要 java List 时,Buffer 却没有发生 JavaConversions._ ?

php - Codeigniter 如何设置 API key 和资源 URL 以便在应用程序中轻松访问