如果有人对以下内容采取创造性方法,那就很好奇:
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
}
答案 0 :(得分:4)
您可以使用
def doubleFromAny(in: Any): Option[Double] = {
Try{in.asInstanceOf[{def toDouble: Double}].toDouble}.toOption
}
这个问题是通过隐式提供的任何toDouble
都不起作用(因此字符串"4.5"
会给你None
)。我也期望表现不会很好。
最后,你需要弄清楚哪些类型是可能的,并使用类似Jon Anderson的答案来检查和演员。
答案 1 :(得分:3)
您可以使用模式匹配。这样做的另一个好处是可以更明确地控制转换的执行方式。 (例如,如果你想尝试额外的字符串解析)
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
}
}
答案 2 :(得分:1)
def toDouble(a: Any): Option[Double] = try {
if (a == null) None else {
Some(a.toString.toDouble)
}
} catch {
case scala.util.control.NonFatal(e) => None
}
答案 3 :(得分:-1)
其他人提出了很好的答案。我想做的另一种方法是使用隐式对象。对于上面的示例,您可以编写如下内容:
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
抱歉。希望这对你有用。