2 Stimmen

Anonyme Funktionen und Karten in Scala

Ich bin mir nicht sicher, warum das nicht funktioniert:

scala> case class Loader(n: String, x: String, l: List[String])
scala> val m: Map[String, (List[String])=>Loader] = 
     | Map("x" -> Loader("x", "x1", _:List[String]))              

<console>:8: error: type mismatch;
 found   : (List[String]) => (java.lang.String, Loader)
 required: (String, (List[String]) => Loader)
       Map("x" -> Loader("x", "x1", _:List[String]))

aber das hier schon?

scala> Loader("t", "x", _:List[String])
res7: (List[String]) => Loader = function1>

scala> val m = Map("x" -> res7)
m: scala.collection.immutable.Map[java.lang.String,(List[String]) => Loader] =
  Map((String,function1>))

5voto

Daniel C. Sobral Punkte 290004

Ein weiteres Opfer der Überlastung durch _ in Scala. Bedenken Sie dies:

f(_, 5) + 1 // Partial function application
f(_ + 1, 5) // Closure

Im ersten Fall, _ ersetzt den gesamten Parameter. In diesem Fall steht er für eine teilweise Anwendung von f . In der Praxis ist dies gleichbedeutend mit x => f(x, 5) + 1 als der gesamte Ausdruck, der enthält f in einen Abschluss umgewandelt wird.

Im zweiten Fall, _ Teil eines Ausdrucks ist. In diesem Fall wird der gesamte Ausdruck bis zu einem beliebigen Ausdrucksbegrenzer in eine Schließung umgewandelt, d. h., wenn der Ausdruck in einem anderen verschachtelt ist, wird nur der innere Ausdruck in eine Schließung umgewandelt. In der Praxis ist dies äquivalent zu f(x => x + 1, 5) .

4voto

Debilski Punkte 65106

Der Parser war sich nicht sicher, wo er den Anfang der anonymen Funktion einfügen sollte. Manchmal können Sie dieses Problem lösen, indem Sie ein weiteres Klammerpaar hinzufügen (allerdings nicht immer):

val m: Map[String, (List[String])=>Loader] =
Map("x" -> (Loader("x", "x1", _:List[String])))

Ich sehe hier keine Zweideutigkeiten, also war er vielleicht einfach nicht schlau genug, um es herauszufinden. Ich denke, der Parser hat die Möglichkeit übersehen, eine anonyme Funktion direkt nach dem -> (das ebenfalls ein Bibliothekskonstrukt ist und die implizit Magie und all das Wicket-Zeug, das den kleinen Parser in die Irre führt).

Wenn Sie es als explizites Tupel schreiben, wird es gut funktionieren.

val m: Map[String, (List[String])=>Loader] =
Map(("x", Loader("x", "x1", _:List[String])))

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X