2013-09-25 8 views
18

Ich habe Schwierigkeiten, spezifische Antworten zu finden, was ich weiß, ist etwas Triviales. Ich würde gerne verstehen, wie Blöcke in Scala funktionieren. Ich komme aus einem Java/Ruby-Hintergrund und es scheint, dass Scala eine völlig andere Art der Verwendung von Blöcken hat.Understanding Scala Blocks

Der folgende Code stammt von der Play! Framework website. Ich würde gerne wissen, was Aktion ist semantisch. Ist es ein Objekt oder eine Funktion, die einen Block akzeptiert, oder auch nicht?

object Application extends Controller { 

    def index = Action { 
    Ok(views.html.index("Your new application is ready.")) 
    } 

} 

Wenn es eine Funktion ist, vielleicht ist es syntaktischer Zucker für die folgende (in diesem Fall, wie scala hinter den Kulissen um Blöcke übertragen wird):

def index = Action({ 
    Ok(views.html.index("Your new application is ready.")) 
    }) 

Oder ist es etwas scala Syntax I‘ mir nicht bewusst.

Jede Bezugnahme auf Scala Quellcode würde mir helfen zu verstehen, wie dies im Hintergrund funktioniert.

Antwort

21

Sie sollten besser über Scala-Blöcke als anonyme Java-Klassen (z. B. Guava-Funktionen) als über Ruby-Blöcke nachdenken. Eigentlich sprechen, wenn Sie scala Code dekompilieren werden Sie mehr oder weniger den gleichen Code (taken from Guava examples) siehe:

Function<String, Integer> lengthFunction = new Function<String, Integer>() { 
    public Integer apply(String string) { 
    return string.length(); 
    } 
}; 

Der Unterschied besteht darin, dass scala viel Syntax Zucker liefert und ermöglicht es Ihnen, über Code zu schreiben, wie:

val lengthFunction = { string: String => string.length } 

Wie für eine bestimmte Aktion Beispiel:

def index = Action({ 
    Ok(views.html.index("Your new application is ready.")) 
    }) 

Hier Aktion ist wahrscheinlich Objekt mit Verfahren anzuwenden. Eine andere Scala Zucker: Sprache können Sie Foo(bar) schreiben und Foo.apply(bar) bedeuten.Als nächstes you can drop round braces when your call isn't ambiguous, also ja, es ist eigentlich eine Methode, die wie genannt wurde:

def index = Action({ 
    Ok(views.html.index("Your new application is ready.")) 
}) 

Und haben so etwas wie dies als Signatur:

object Action { 
    def apply(block: => Result) = ??? 
} 

Wie schon gesagt von @yan ist es scala Art und Weise zu sagen hey, ich bin eine Funktion, die eine andere Funktion übernehmen, die

entzuckert Aufruf wie

Ergebnis erzeugtaussehen
def index = Action.apply(new AbstractFunction[Result] { 
     def apply() = Ok.apply(views.html.index.apply("...")) 
}) 
8

Hier gibt es ein paar Dinge. Action ist ein Objekt, das eine apply() Methode implementiert, was aufgerufen wird, wenn Sie das Objekt als eine Funktion behandeln. Es gibt ein paar apply()implementations. Die erste Implementierung verwendet einen Parameternamen.

Scala unterstützt ein Konzept namens 'by-name parameters', die wie normale Parameter sind, außer dass sie nur ausgewertet werden, wenn der Code ausgeführt wird, der auf sie verweist. Sie helfen bei der Erstellung von Konstrukten, die wie Teile der Sprache erscheinen, ohne auf Makros zurückgreifen zu müssen. In diesem Fall ist der Block, der Ok(..) umgibt, nur ein regelmäßiger Block von Anweisungen, wobei der Wert des letzten als der Wert des Blocks verwendet wird. Das von Ihnen angegebene Beispiel funktioniert auch ohne die geschweiften Klammern. Sie geben das Ergebnis von Oks apply-Methode im Wesentlichen an Actions apply-Methode weiter.

Die zweite Version von apply() nimmt tatsächlich eine vollständige anonyme Funktion, die eine Anfrage auf ein Ergebnis abbildet. In diesem Fall können Sie eine anonyme (oder benannte) Funktion übergeben.

+0

Danke für die Antwort. Also von dem, was ich sammle, ist dies syntaktischer Zucker für Action.apply(). Entfernen des Zuckers, wie würde die gesamte Aussage aussehen? – b1nd

+0

Die Anweisung, wie Sie sie haben, ist im Wesentlichen 'Action.apply (Ok.apply (views.html.index) (" Ihre neue Anwendung ist fertig. "))). Wenn Sie sich die Definition von 'apply()' in der von mir angegebenen URL ansehen, bemerken Sie einen Pfeil vor dem Typ des Parameters. Das markiert ihn nur als "Name" -Parameter, wie oben beschrieben. (Es ist auch kein Zufall, dass die Syntax für den Namen wie die einer anonymen Funktion ohne Argumente aussieht) – yan

+0

Link zum Abspielen doc ist übrigens kaputt. Gelegentlich vermasselt der SO-Parser Links, die ein Dollarzeichen enthalten. –