2017-02-24 9 views
2

Ich muss einige Rohdaten analysieren und ich bin gezwungen, mit Any Typ zu arbeiten. Wenn die Daten, die ich lese, in irgendeinem numerischen Format (Int/Double/Long/...) sind, muss ich es in Double konvertieren, sonst (z. B. String) muss ich es leer lassen. Das habe ich mir ausgedacht:Scala Möglichkeit, eine beliebige Zahl in Double zu konvertieren

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 
    } 

Das sieht offensichtlich nicht einmal anständig aus. Gibt es einen besseren Weg, damit in Scala umzugehen?

Antwort

4

Sobald Sie Ihre Typinformationen bei der Kompilierung verloren, wie es in Ihrem Fall sein geschieht, da Ihr Eingangstyp Any als Teil seiner Voraussetzungen ist, gibt es keine mehr Möglichkeiten als expectedNumber zur Laufzeit mit isInstanceOf Inspektion.

Dies wird durch die Implementierung der Mustererkennung, die Sie in Ihrer vorgeschlagenen Lösung durchführen, maskiert. Und ich denke, das ist die beste Lösung in Ihrem Fall.

Es gibt jedoch eine Alternative, die Try über und wandelt es in eine Option. zB:

Try(expectedNumber.toString.toDouble).toOption 

, die in vielerlei Hinsicht eine schmutzige Lösung ist (nicht effizient auf alle Ausnahmen mit Fluss zu steuern, ...), dass würde ich definetively ersten Ansatz verwenden

+0

Traurig, es zu hören, aber ich denke, Sie haben Recht;) – 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 Dies beantwortet nicht oder nur teilweise, OPs Frage. Sie sagten, dass sie die 'Any' Parameter zu verwenden sind gezwungen, und auch funktioniert nur, wenn Sie eine' String' haben (was natürlich leicht erreicht, aber schweift aus dem ursprünglichen Problem). – Adowrath

+0

Das ist ein guter Punkt ... das parseDouble kann als def parseDouble (s: Any) modifiziert werden: Option [Double] = Versuchen Sie {s..toString.toDouble} .toOption –

+0

Aber dann ist es ungefähr dasselbe wie Pablo, aber ohne die Warnungen, warum es eine schlechte Idee ist. – Adowrath

2

Es ist durchaus möglich, wie in this Antwort angegeben:

Verwenden java.lang.Number passend zu Ihrem Falltyp.

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

Beachten Sie, dass dies funktioniert auch für Fälle von BigDecimal und BigInteger, sei es scala.math.BigDecimal oder java.math.BigDecimal.

+0

Dies scheint ein guter formaler Weg zu sein. Vielen Dank – Jake

Verwandte Themen