Frage

Wie wird Arbeit Option Monade gemeint? Ich bin das Surfen im scala api und es ist ein Beispiel (I die zweiten bedeuten),

  

Weil, wie für das Verständnis funktioniert, wenn kein von request.getParameter zurückgegeben wird, die gesamte Ausdruck Ergebnisse in None

Aber wenn ich versuche, diesen Code ein:

 val upper = for {
   name <- None //request.getParameter("name")
   trimmed <- Some(name.trim)
   upper <- Some(trimmed.toUpperCase) if trimmed.length != 0
 } yield upper
 println(upper.getOrElse(""))

Ich bekomme einen Compiler-Fehler. Wie soll das denn funktionieren?

War es hilfreich?

Lösung

Sie einen Compiler-Fehler erhalten, weil dies

  name <- None

Auf diese Weise wird die Art des None zu None.type gesetzt und die Variable name wird abgeleitet vom Typ Nothing sein. (Das heißt, würde es diese Art hat, wenn es existiert tatsächlich aber offensichtlich die für das Verständnis nicht einmal, um es zur Laufzeit zu schaffen.) Daher ist keine Methode name.trim existiert, und es wird nicht kompiliert.

Wenn Sie request.getParameter("name") zur Verfügung hätte, würde seine Art sein Option[String], name würde möglicherweise Typ String haben und name.trim würde kompilieren.

Sie können dies umgehen, indem Sie die Art der None Angabe:

  name <- None: Option[String]

Andere Tipps

Um auf Kevins Antwort zu erweitern, Sie Verpackung Werte in Some() unter Verwendung des = Operator anstelle des <- Betreiber vermeiden kann:

val upper = for {
   name <- None: Option[String] //request.getParameter("name")
   trimmed = name.trim
   upper = trimmed.toUpperCase if trimmed nonEmpty
} yield upper

Das für Verständnis zu etwas sehr ähnlich zu Kevins Version kompilieren, aber wir finden es oft klarer map und filter explizit zu vermeiden Unordnung (zB zusätzliche Variablennamen) hinzufügen, dass nichts auf den semantischen Inhalt des Ausdrucks zu verwenden.

Um auf Debilski Antwort zu erweitern, Sie brauchen auch nicht explizit nachfolgende Werte in Some() wickeln, der einzige Wert, sind Sie tatsächlich über die Abbildung ist die ursprüngliche name.

Ein besserer Ansatz die map und filter Operationen direkt anstelle eines für Verständnis zu verwenden sein würde:

Hinweis: hinter den Kulissen wird der Scala-Compiler eines konvertieren für Verständnis auf eine Kombination von Karte / flatMap / Filter wie auch immer, so dass dieser Ansatz nie weniger effizient sein wird als ein für Verständnis und gut sein kann effiziente

def clean(x:Option[String]) = x map { _.trim.toUpperCase } filterNot { _.isEmpty }

val param = None : Option[String] // request.getParameter("name")
println( clean(param).getOrElse("") )
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top