4 Stimmen

Warum ist dieser "Fall" unbedingt erforderlich?

object Test1 {
    def main(args: Array[String]) {
        val list = List("a", "b")
        list map { x  println(x) }
        list map { case x  println(x) }

        val list2 = List(("aa", "11"))
        list2 map {
            case (key, value)  println("key: "+key+", value: "+value)
        }
    }

}

Bitte beachten Sie in der letzten Zeile, warum das Schlüsselwort case muss verwendet werden, aber die list map { x println(x) } es entfernen kann?

14voto

thoredge Punkte 11646

Sie können das Tupel in der Funktion literal nicht aufbrechen. Deshalb müssen Sie stattdessen case verwenden, um sie abzugleichen. Eine andere Möglichkeit ist die Verwendung von tupled um Ihre Funktion mit zwei Argumenten passend zu machen:

import Function.tupled 
list2 map tupled {
  (key, value) => println("key: "+key+", value: "+value)
}

9voto

Daniel C. Sobral Punkte 290004
{ case (key, value) => f }

ist nicht dasselbe wie

{ (key, value) => f }

Die erste ist eine Musterübereinstimmung, die eine Tuple2 in seine Bestandteile zerlegt und deren Werte den key y value . In diesem Fall wird nur ein Parameter übergeben (das Tupel). { x => println(x) } funktioniert, weil x wird das Tupel zugewiesen, und println druckt es aus.

Die zweite ist eine Funktion, die zwei Parameter benötigt und keinen Mustervergleich durchführt. Da map eine Funktion erfordert, die einen einzigen Parameter annimmt, ist der zweite Fall unvereinbar mit map .

4voto

list2 hat Elemente des Typs Tuple2[Int, Int] , also die Signatur der Funktion, die Sie map übergeben müssen (in diesem Fall ... foreach ist eine natürlichere Wahl, wenn man etwas nicht zurückgibt) ist Tuple2[Int, Int] => Unit . Das heißt, er nimmt ein einziges Argument vom Typ Tuple2[Int, Int] .

Da Tuple2 unterstützt unapply können Sie den Mustervergleich verwenden, um dieses Tupel innerhalb Ihrer Funktion aufzubrechen, wie Sie es getan haben:

{
  case (key, value)  println("key: "+key+", value: "+value)
}

Die Signatur dieser Funktion ist nach wie vor Tuple2[Int, Int] => Unit

Es ist identisch mit und kompiliert wahrscheinlich zu den gleichen Bytecodes wie:

{
  x: Tuple2[Int, Int] => println("key: "+x._1+", value: "+x._2)
}

Dies ist eines von vielen Beispielen, in denen Scala orthogonale Konzepte auf sehr ansprechende Weise kombiniert.

3voto

Landei Punkte 53286

list2 map { x => println(x) } funktioniert bei mir ohne Probleme. Wenn Sie einen Musterabgleich (Aufteilung des Arguments in seine Bestandteile entsprechend seiner Struktur) wünschen, müssen Sie immer case . Alternativ können Sie auch schreiben:

list2 map { x => println("key: "+x._1+", value: "+x._2) }

ÜBRIGENS, map sollte verwendet werden, um umwandeln eine Liste in einer anderen. Wenn Sie nur alle Elemente einer Liste durchgehen wollen, verwenden Sie foreach oder zum Verstehen.

1voto

Andy Punkte 4948

Ich bin noch lernen Scala, aber ich glaube, was passiert ist, dass Sie eine partielle Funktion definiert haben, die ein Argument. Beim Aufrufen von Methoden wie List.map oder List.foreach, die nur ein Argument benötigen, können Sie den Unterstrich oder den Namen val weglassen.

Beispiel für die Auslassung des Val-Namens im Abschluss:

val v = List("HEY!", "BYE!")
v.foreach { Console.println } // Pass partial function, automatically

Dies ist dasselbe wie:

val v = List("HEY!", "BYE!")
v.foreach { Console.println _ } // Pass partial function, explicitly

Die Verwendung des anonymen val:

val v = List("HEY!", "BYE!")
v.foreach { Console.println(_) } // Refer to anonymous param, explicitly

Oder Sie verwenden einen benannten Wert:

val v = List("HEY!", "BYE!")
v.foreach { x => Console.println(x) } // Refer to val, explicitly

In Ihrer Schließung verwenden Sie eine Teilfunktion (die case-Anweisung), die eine anonyme Variable nimmt und sie sofort in ein Tupel verwandelt, das an zwei separate Variablen gebunden ist.

Ich glaube, ich habe mich bei einem der obigen Ausschnitte vertan. Wenn ich zu meinem Arbeitscomputer komme, werde ich das in der REPL überprüfen.

Werfen Sie auch einen Blick auf Funktion Currying in Scala für einige weitere Informationen.

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