2017-02-24 203 views
2

我需要做一些原始数据解析,我不得不使用Any类型。如果我读取的数据是任何数字格式(Int/Double/Long/...),我需要将它转换为double,否则(例如String)我需要将其保留为空。这是我想出来的:斯卡拉方式将任意数字转换为双数

def extractDouble(expectedNumber: Any): Option[Double] = expectedNumber match { 
    case i: Int => Some(i.toDouble) 
    case l: Long => Some(l.toDouble) 
    case d: Double => Some(d) 
    case _ => None 
    } 

这obvoiusly看起来并没有甚至体面。在scala中有没有更好的方法来处理这个问题?

回答

4

一旦你在编译时丢失了您的类型信息,因为它发生在你的情况,因为你的输入类型是Any作为其要求的一部分,还有比在运行时isInstanceOf检查expectedNumber没有更多的选择。

这是由您在您提出的解决方案中执行的类型模式匹配的实现所掩盖。我认为这是您案例中的最佳解决方案。

但是,有一种替代方法是使用Try并将其转换为Option。例如:

Try(expectedNumber.toString.toDouble).toOption 

这是一个在很多方面一个肮脏的解决方案(没有效率可言,用异常来控制流量,...),其我会definetively使用第一种方法

+0

很难听到它,但我想你是对的;) – Niemand

1
import scala.util.Try  
def parseDouble(s: String): Option[Double] = Try { s.toDouble }.toOption 

Scala is a string parseable as a double

+0

-1这不,或只是部分回答OP的问题。他们说,他们被迫使用'Any'参数,并且只有当你有一个'String'时(这当然很容易实现,但是从原始问题中离题)。 – Adowrath

+0

这是好点... parseDouble可以修改为def parseDouble(s:Any):Option [Double] = Try {s..toString.toDouble} .toOption –

+0

但是,它与Pablo大致相同,但没有为什么这是一个坏主意的警告。 – Adowrath

2

这当然是可能的,如this答复中指出:

使用java.lang.Number以匹配您的案例类型。

def extractDouble(x: Any): Option[Double] = x match { 
    case n: java.lang.Number => Some(n.doubleValue()) 
    case _ => None 
} 

注意,这也适用于的BigDecimalBigInteger情况下,无论是scala.math.BigDecimaljava.math.BigDecimal

+0

这似乎是一个很好的正式方式来做到这一点。谢谢 – Jake