Was macht das Wort "Action" in einer Scala-Funktionsdefinition mit dem Play-Framework?

8

Ich entwickle Play-Anwendung und ich habe gerade mit Scala begonnen. Ich sehe, dass es das Wort Action nach dem Gleichheitszeichen in der Funktion unten und vor der geschweiften Klammer gibt.

%Vor%

Was macht dieser Code? Ich habe gesehen, dass es mit def index = { verwendet wurde, aber nicht mit dem Wort vor der geschweiften Klammer.

Ich würde annehmen, dass der Name der Funktion index ist. Aber ich weiß nicht, was das Wort Action in dieser Situation macht.

    
Johnston 31.01.2015, 02:32
quelle

3 Antworten

9

Die anderen Antworten beziehen sich auf Ihren speziellen Fall. Sie haben jedoch nach dem allgemeinen Fall gefragt, also werde ich versuchen, aus dieser Perspektive zu antworten.

Zuerst wird def verwendet, um eine Methode zu definieren , nicht eine Funktion (besser, diesen Unterschied jetzt zu lernen). Aber Sie haben Recht, index ist der Name dieser Methode.

Im Gegensatz zu anderen Sprachen, mit denen Sie vertraut sind (z. B. C, Java), können Sie in Scala Methoden mit einem Ausdruck definieren (wie durch die Verwendung der Zuweisungsoperatorsyntax = vorgeschlagen). Das heißt, alles nach dem = ist ein Ausdruck , der bei jedem Aufruf der Methode zu einem Wert ausgewertet wird.

In Java muss man also sagen:

%Vor%

In Scala kannst du einfach sagen:

%Vor%

Natürlich ist der Ausdruck in der Regel komplizierter (wie in Ihrem Fall). Es könnte ein Codeblock sein, wie Sie es gewöhnt sind zu sehen, in diesem Fall ist der Wert der des letzten Ausdrucks im Block:

%Vor%

Oder es könnte einen Methodenaufruf auf ein anderes Objekt beinhalten:

%Vor%

Letzteres ist in der Tat genau das, was in Ihrem spezifischen Beispiel vor sich geht, obwohl es ein bisschen mehr Erklärung benötigt, um zu verstehen warum. Es sind zwei Bits Magie beteiligt: ​​

  1. Wenn ein Objekt eine Methode apply hat, können Sie das Objekt so behandeln, als wäre es eine Funktion . Sie können zum Beispiel Add(1, 2) sagen, wenn Sie wirklich Add.apply(1,2) meinen (vorausgesetzt, es gibt natürlich ein Add -Objekt mit einer apply -Methode). Um es klar zu sagen, es muss kein Objekt sein, das mit dem Schlüsselwort object definiert wurde. Jedes Objekt mit einer geeigneten apply -Methode reicht aus.
  2. Wenn eine Methode einen einzelnen nach-name -Parameter hat (z. B. def ifWaterBoiling(fn: => Tea) ), können Sie die Methode wie ifWaterBoiling { makeTea } aufrufen. Der Code in diesem Block wird langsam ausgewertet (und möglicherweise gar nicht ausgewertet). Dies entspricht dem Schreiben von ifWaterBoiling({ makeTea }) . Der { makeTea } -Teil definiert nur einen Ausdruck, der für den Parameter fn übergeben wird, unausgewertet.
Aaron Novstrup 31.01.2015, 07:32
quelle
14

Dieses Wort ist Teil von Play Framework und es ist ein Objekt mit der Methode apply(block: ⇒ Result) , also ist Ihr Code tatsächlich:

%Vor%

Ihre index Methode gibt eine Instanz der Klasse Action[AnyContent] .

Übrigens, Sie übergeben einen Codeblock {Ok(...)} an apply method, der hier als anonyme Funktion fungiert, weil der erforderliche Typ für die Eingabe apply ist nicht nur Result , sondern ⇒ Result , was bedeutet, dass es eine anonyme Funktion ohne Eingabeparameter benötigt, die Result zurückgibt. Also wird Ihr Ok-Block ausgeführt, wenn der Container, der Ihre Instanz der Klasse Action (von der Indexmethode) empfangen hat, entschieden hat, diesen Block auszuführen. Das bedeutet einfach, dass Sie hier nur eine Aktion beschreiben - nicht ausführen - sie wird tatsächlich ausgeführt, wenn Play Ihre Anfrage erhalten hat - und finden eine Bindung zu Ihrer Aktion innerhalb der Routing-Datei.

Sie müssen auch def nicht verwenden, da Sie immer die gleiche Aktion zurückgeben - val oder lazy val ist normalerweise ausreichend. Sie benötigen ein def nur dann, wenn Sie tatsächlich einen Parameter aus der Routing-Tabelle übergeben möchten (zum Beispiel):

%Vor%

Ein anderer möglicher Ansatz besteht darin, Aktion basierend auf dem Parameter auszuwählen:

%Vor%

Aber normalerweise können Sie die Routing-Tabelle selbst dafür verwenden, was besser für die Entkopplung ist. Dieses Beispiel zeigt nur, dass Action nicht mehr als ein Rückgabewert ist.

Update für @ Kazuya

%Vor%

GWT / Scala.js verwenden similar Ansatz für Client-Server-Interaktion. Dies ist nur eine mögliche Lösung, um die Wichtigkeit des von der Routing-Tabelle übergebenen Parameters "methodName" zu erklären. Daher könnte man action als eine Wrapper-over-Funktion betrachten, die wiederum einen Verweis auf die OOP-Methode darstellt, was sie sowohl für REST- als auch für RPC-Zwecke nützlich macht.

    
dk14 31.01.2015 02:48
quelle
4

Es ist der Action , der mit einem Ausdruckblock als Argument aufgerufen wird. (Die Methode apply wird unter der Haube verwendet.)

%Vor%

Ein einfaches Beispiel (von hier ) ist wie folgt (siehe Kommentare im Code):

%Vor%

Jetzt können Sie damit einen anderen Aktionswert umbrechen:

%Vor%

Auch der Fall, den Sie für def index = { erwähnt haben, gibt tatsächlich Unit like: def index: Unit = { zurück.

    
nitishagar 31.01.2015 02:41
quelle

Tags und Links