2014-12-11 18 views
17

L'esempio Scala per passare una funzione a un'altra funzione non ha il caso in cui la funzione passata (timeFlies) accetta un argomento (x).Scala Passing Function con Argomento

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)) 
    } 
} 

Come è possibile eseguire il codice sopra riportato?

Modifica: ho aggiunto una x nella prima per chiarire che l'obiettivo è passare il numero intero.

+0

Avete * veramente * bisogno di passare l'Int a 'oncePerSecond'? Tutte le risposte qui sotto dovrebbero andare bene e sono meglio che passare quella Int. Ad ogni modo, 'oncePerSecond (timeFlies, 5)' e 'def oncePerSecond (callback: Int => Unit, x: Int)' dovrebbe funzionare. – Dimitri

risposta

21

Ci sono almeno due modi per farlo, a seconda di dove esattamente si vuole passare l'argomento nel primo. il modo è dove tieni main come se lo avessi.

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)) 
    } 
} 

L'altro metodo è quello di passare il parametro in corrispondenza del punto della richiamata, in questo modo:

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) 
    } 
} 

noti che timeFlies ha la firma (Int) => Unit, ma timeFlies(5) ha la firma => Unit, a causa di partial application. Ciò significa che è possibile applicare il parametro per creare automaticamente una funzione che richiede meno parametri. oncePerSecond ha bisogno di sapere nella sua firma se hai già applicato il parametro Int alla richiamata o meno.

Entrambi i metodi sono utili per diversi casi d'uso. Il primo modo consente a oncePerSecond di non conoscere i parametri del callback. Il secondo modo ti consente di modificare il valore di x ogni volta che lo desideri.

+0

Risposta del modello. Grazie. – BAR

+0

nel primo modo 'callback: => Unità' c'è comunque per preservare il 'tipo' della funzione che voglio passare? 'callback: => Unit' è così generale, vorrei dire esattamente quale tipo di funzione mi aspetto ... – Jas

+0

No. L'intero punto di utilizzo di tale metodo sarebbe se non si desidera conoscere il tipo non applicato. –

2

oncePerSecond(() => timeFlies(5))

o

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

3

Il tipo di ritorno timeFlies saranno Unit, non Function. Forse volevi dire:

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

Il parametro callback:() => Unit è una funzione zero parametro che restituisce Unit. Si dovrebbe fare call-by-nome del parametro (cosa che restituisce Unit):

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

E questo è stato downvoted, perché? –

Problemi correlati