Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 有什么方法可以使这些用默认值转换数字的函数干涸?_Scala_Dry - Fatal编程技术网

Scala 有什么方法可以使这些用默认值转换数字的函数干涸?

Scala 有什么方法可以使这些用默认值转换数字的函数干涸?,scala,dry,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

我有很多这样的功能:

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

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

您可以利用
数值来避免重复零

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

尽管克里斯·马丁的答案可能是最复杂的,但它相当复杂。您可以通过使用返回函数的函数来封装“try something,or get me the default”

 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
返回一个函数,该函数在引发异常时使用默认值对字符串进行转换


您可以将此
转换器
用于可能引发异常的任何转换,而不仅仅是数值。

虽然在技术上很有趣,但我想知道该解决方案增加的复杂性如何与@don mackenzie提出的简单三行相比。一句简单的话:提高代码的可维护性。我想我并不认为它有那么有趣或复杂。为什么这么复杂?因为它使用上下文边界?因为LoC更高?因为得到的方法更抽象?这不是意图的最直接表达吗?[x]以上所有内容。