好奇是否有人在以下方面有创造性的方法:
def toDouble(any: Any): Option[Double] = // { if any has a .toDouble method call it else return None }
例如,Int,String,Long都有一个.toDouble方法。如果它存在(即使是非基元类型(,我希望它被调用。
理想情况下是这样的(没有 .toString'先处理所有内容(
def toDouble(any: Any): Option[Double] = {
case any.hasToDouble => Try(any.toDouble).toOption
case _ => None
}
def doubleFromAny(in: Any): Option[Double] = {
Try{in.asInstanceOf[{def toDouble: Double}].toDouble}.toOption
}
这样做的问题是通过隐式提供的任何toDouble
都不起作用(因此字符串"4.5"
会给你None
(。 我也预计性能不会很好。
最后,你需要弄清楚哪些类型是可能的,并使用乔恩·安德森的答案来检查和投射每种类型。
您可以使用模式匹配。 这还有一个额外的好处,即您可以更明确地控制转换方式。 (例如,如果您想尝试额外的字符串解析(
def toDouble(any: Any): Option[Double] = {
any match {
case n:Int => Some(n.toDouble)
case n:Long => Some(n.toDouble)
case n:Double => Some(n.toDouble)
case s:String => Try(s.toDouble).toOption
case _ => None
}
}
def toDouble(a: Any): Option[Double] = try {
if (a == null) None else {
Some(a.toString.toDouble)
}
} catch {
case scala.util.control.NonFatal(e) => None
}
其他人提出了很好的答案。我想到的另一种方法是使用隐式对象。对于上面的例子,你可以写一些东西:
sealed trait ImplicitType[T]
object ImplicitType{
implicit object IntType extends ImplicitType[Int]
implicit object StringType extends ImplicitType[String]
implicit object LongType extends ImplicitType[Long]
implicit object DoubleType extends ImplicitType[Double]
}
def toDouble[T : ImplicitType](n: T) : Option[Double] = {
Try(n.toString.toDouble).toOption
}
上述工作是因为编译器约束来自ImplicitType
配套对象中隐式对象的可用性。上下文绑定隐式 def f: ImplicitType[T] 默认搜索 ImplicitType
的配套对象内的隐式对象。所以现在你可以做这样的事情:
val foo = toDouble(1) // Some(1.0)
val foo1 = toDouble("2") //Some(2.0)
val foo2 = toDouble(1L) //Some(1.0)
val foo3 = toDouble("s") //None
val foo4 = toDouble(1.23456e300d) //Some(1.23456E300)
这样,您的toDouble
功能根本不会改变。我想不出避免toString
抱歉的方法。希望这对你有用。