2014-12-11 13 views
17

W przykładzie Scala przekazywania funkcji do innej funkcji brakuje przypadku, w którym przekazana funkcja (timeFlies) przyjmuje argument (x).Scala przekazująca funkcję z argumentem

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

Jak mogę wykonać powyższy kod?

Edytuj: Dodałem x w ciągu 1 sekundy, aby wyjaśnić, że celem jest przekazanie liczby całkowitej.

+0

Czy naprawdę * potrzebujesz przekazać Int do 'oncePerSecond'? Wszystkie poniższe odpowiedzi powinny być w porządku i lepsze niż przekazanie tego Int. W każdym razie, 'oncePerSecond (timeFlies, 5)' i 'def oncePerSecond (callback: Int => Unit, x: Int)' powinny działać. – Dimitri

Odpowiedz

21

Istnieją co najmniej dwa sposoby, można to zrobić, w zależności od tego, gdzie dokładnie chcesz przekazać argument w pierwszej kolejności. droga jest tam, gdzie trzymasz main, jakbyś ją miał.

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

Drugą metodą jest przekazać parametr w co punktu zwrotnego, tak:

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

Zauważ, że timeFlies ma sygnaturę (Int) => Unit, ale timeFlies(5) ma sygnaturę => Unit, z powodu partial application. Zasadniczo oznacza to, że można zastosować parametr, aby automatycznie utworzyć funkcję, która wymaga mniejszej liczby parametrów. oncePerSecond potrzebuje znać w swoim podpisie, jeśli już zastosowałeś parametr Int do wywołania zwrotnego, czy też nie.

Obie metody są przydatne w różnych przypadkach użycia. Pierwszy sposób pozwala oncePerSecond nie wiedzieć o parametrach wywołania zwrotnego. Drugi sposób pozwala zmienić wartość x za każdym razem w pętli, jeśli chcesz.

+0

Model odpowiedź. Dziękuję Ci. – BAR

+0

w pierwszy sposób "callback: => Unit" czy tak jest, aby zachować "typ" funkcji, którą chcę przekazać? 'callback: => Unit' jest tak ogólny, chciałbym dokładnie powiedzieć, jakiego rodzaju funkcji oczekuję ... – Jas

+0

Nie. Cały sens używania tej metody byłby, gdybyś nie chciał znać nie stosowanego typu. –

2

oncePerSecond(() => timeFlies(5))

lub

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

3

typu powrót timeFlies będzie Unit nie Function. Może chodziło:

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

Parametr callback:() => Unit jest funkcją zerową parametrem, który zwraca Unit. Należy zrobić to zadzwonić po nazwie parametru (coś że ocenia się Unit):

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

A to zostało odrzucone, ponieważ? –

Powiązane problemy