2014-12-11 13 views
17

Das Scala-Beispiel für die Übergabe einer Funktion an eine andere Funktion fehlt der Fall, in dem die übergebene Funktion (timeFlies) ein Argument (x) nimmt.Scala-Passing-Funktion mit Argument

object Timer { 
    def oncePerSecond(callback: (Int) => Unit) { 
    while (true) { callback(x); Thread sleep 1000 } 
    } 
    def timeFlies(x: int) { 
    println("time flies like an arrow...") 
    } 
    def main(args: Array[String]) { 
    oncePerSecond(timeFlies(5)) 
    } 
} 

Wie kann ich den obigen Code arbeiten lassen?

Edit: Ich fügte ein x in der onepersecond, um das Ziel zu klären, ist die Ganzzahl übergeben.

+0

Müssen Sie * wirklich * den Int an 'oncePerSecond' übergeben? Alle Antworten sollten in Ordnung sein und sind besser als das Int. Wie auch immer, 'oncePerSecond (timeFlies, 5)' und 'def oncePerSecond (Rückruf: Int => Unit, x: Int)' sollte funktionieren. – Dimitri

Antwort

21

Es gibt mindestens zwei Möglichkeiten, wie Sie es tun können, je nachdem, wo genau wollen Sie in das Argument zu übergeben: Die erste. Weg ist, wo Sie main halten, wie Sie es hatten.

object Timer { 
    def oncePerSecond(callback: => Unit) { 
    while (true) { callback; Thread sleep 1000 } 
    } 
    def timeFlies(x: Int) { 
    println("time flies like an arrow...") 
    } 
    def main(args: Array[String]) { 
    oncePerSecond(timeFlies(5)) 
    } 
} 

Die andere Methode ist es, die Parameter in an der Stelle des Callback passieren, wie folgt aus:

object Timer { 
    def oncePerSecond(callback: (Int) => Unit) { 
    val x = 5 
    while (true) { callback(x); Thread sleep 1000 } 
    } 
    def timeFlies(x: Int) { 
    println("time flies like an arrow...") 
    } 
    def main(args: Array[String]) { 
    oncePerSecond(timeFlies) 
    } 
} 

anzumerken, dass timeFlies die Signatur (Int) => Unit, aber timeFlies(5) hat die Signatur => Unit wegen partial application. Dies bedeutet im Wesentlichen, dass Sie den Parameter anwenden können, um automatisch eine Funktion zu erstellen, die weniger Parameter benötigt. oncePerSecond muss in seiner Signatur wissen, ob Sie den Int Parameter bereits auf den Rückruf angewendet haben oder nicht.

Beide Methoden sind für verschiedene Anwendungsfälle nützlich. Die erste Möglichkeit lässt oncePerSecond nicht über die Parameter des Rückrufs wissen. Die zweite Möglichkeit lässt Sie den Wert von x jedes Mal durch die Schleife ändern, wenn Sie möchten.

+0

Modellantwort. Vielen Dank. – BAR

+0

auf die erste Art und Weise 'Callback: => Einheit' gibt es sowieso, um den 'Typ' der Funktion zu erhalten, die ich weitergeben will? 'Callback: => Unit' ist so allgemein, ich würde gerne genau sagen welche Art von Funktion ich erwarte ... – Jas

+0

Nein. Der Sinn dieser Methode liegt darin, dass Sie den nicht verwendeten Typ nicht kennen. –

2

oncePerSecond(() => timeFlies(5))

oder

def oncePerSecond(callback: => Unit) {...

3

Der Rückgabetyp timeFlies wird Unit, nicht Function. Vielleicht meinte Sie:

oncePerSecond(() => timeFlies(5)) 
0

Der Parameter callback:() => Unit ist ein Null-Parameter-Funktion, die Unit zurückgibt. Sie sollten es Call-by-Namen machen Parameter (etwas, das zu Unit auswertet):

def oncePerSecond(callback: => Unit) = ... 
+1

Und das wurde downvoted, weil? –