2017-03-22 7 views
3

Ich versuche, eine Funktion mit der variablen Anzahl von ArgumentenScala Fall Mustererkennung Fehler bei Option [Zeichenfolge]

def foo(args: String*) 

zu erstellen Was diese Funktion macht, ist, beseitigt es die leeren Saiten und separaten Rest die Zeichenfolgen mit einem Komma (,).

def foo(args: String*) = { 
    args.flatMap { 
    case str if str.isEmpty => None 
    case str => Some(str) 
    }.mkString(", ") 
} 

Wenn ich diese Funktion Option[String] Argumente

def foo(args: Any*) = { 
    args.flatMap { 
    case str: String if str.isEmpty => None 
    case str: Option[String] if str.getOrElse("").isEmpty => None 
    case str => Some(str) 
    }.mkString(", ") 
} 

Ich habe eine Warnung sagen

warning: non-variable type argument String in type pattern Option[String] is unchecked since it is eliminated by erasure

Und wenn ich Argumente übergeben

foo("", "Hello", Some(""), Some("what")) 

Ich habe zur Unterstützung erweitert Fehler

scala.MatchError: Some(what) (of class scala.Some) at $anonfun$makeAddress$1.apply(:12) at $anonfun$makeAddress$1.apply(:12)

Wie soll ich eine solche Funktion unterstützt Option[String] auch schaffen?

+0

Ich habe eine mögliche Lösung https://gist.github.com/fahdsiddiqui/b530a093a643f489a9a661606d479f30, aber lassen Sie mich bitte wissen, wenn es eine optimale Lösung gibt. –

+0

Auch https://stackoverflow.com/questions/16056645/how-to-pattern-match-on-generic-type-in-scala – danielnixon

+0

Verwenden von 'Any' ist ein starker Code-Geruch - es ist der Anfang der [Type Hierarchy ] (docs.scala-lang.org/tutorials/tour/unified...). Als Ergebnis kann der Compiler Ihnen nicht helfen, d. H. Laufzeitfehler verhindern, da der Typ angesichts seiner Breite nicht nützlich ist. –

Antwort

3

könnten Sie sammeln und Option ganz vermeiden:

def foo(args: String*): String = { 
    args.collect{case s if ! s.isEmpty => s}.mkString(",") 
} 

sammeln ist das Äquivalent des Filters mit Karte kombiniert.

1

Ähnlich wie Ihre Lösung

def foo(args: Any*) = { 
    args.flatMap { 
    case str: String if !str.isEmpty => Option(str) 
    case Some(str:String) if !str.isEmpty => Option(str) 
    case _ => None 
    }.mkString(", ") 
} 
+0

Darüber hinaus gibt es in Ihrem Code einen Fehler, wenn Sie unter println verwenden (foo ("", "Hallo", Einige (null), Einige ("was"))) –

+0

sollte es nicht Einige sein (str) statt Option (str)? –

+1

Nein, Some (str) wird hauptsächlich für Mustervergleiche verwendet. Das Problem ist Some (null)! = None und Option (null) == None. Sie können in scala REPL versuchen. –

Verwandte Themen