2014-12-11 19 views
17

Bir işlevi başka bir işleve iletme örneği, geçirilen işlevin (timeFlies) bir argüman (x) alması durumundan yoksundur.Argüman ile Scala Geçiş İşlevi

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

Yukarıdaki kodu nasıl çalıştırabilirim?

Düzenleme: Tamsayıyı geçmenin amacı olduğunu netleştirmek için bir defada tersine bir x ekledim.

+0

Siz * gerçekten * Int'i 'oncePerSecond' olarak iletmeniz gerekiyor mu? Aşağıdaki tüm cevaplar iyi olmalı ve Int. Neyse, bir kerePerSecond (timeFlies, 5) 've' def defolu bir kerePerSecond (geri arama: Int => Birim, x: Int) 'çalışmalıdır. – Dimitri

cevap

21

Eğer içinde argüman geçirmek istediğiniz tam olarak nerede dayanarak bunu yapabilir, en az iki yolu vardır ilk. yolu, sahip olduğunuz main'u sakladığınız yerdir.

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

bir başka yöntem, bu gibi geri arama noktasında parametre geçmektir: timeFlies imza (Int) => Unit sahiptir

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

Not, ama timeFlies(5) nedeniyle, imza => Unit sahip partial application. Bu temel olarak, daha az parametre alan bir işlevi otomatik olarak oluşturmak için parametreyi uygulayabileceğiniz anlamına gelir. Int parametresini daha önce geri çağırma işlemine uyguladıysanız, oncePerSecond imzasında bilmesi gerekir.

Her iki yöntem de farklı kullanım durumları için kullanışlıdır. İlk yol, oncePerSecond'un geriçağırımın parametrelerini bilmesine izin vermez. İkinci yol, isterseniz her zaman döngü boyunca x değerini değiştirmenizi sağlar.

+0

Model yanıtı. Teşekkür ederim. İlk olarak – BAR

+0

'geri arama: => Birim' geçmek istediğim işlevin 'tipini' korumak için zaten var mı? 'Geri arama: => Birim 'çok genel, tam olarak ne tür bir fonksiyon beklediğimi söylemek istiyorum ... – Jas

+0

Nope. Uygulanmayan türü bilmek istemiyorsanız, bu yöntemi kullanmanın tüm noktası olurdu. –

2

oncePerSecond(() => timeFlies(5))

veya

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

3

timeFlies dönüş tipi Unit değil Function olacaktır. Belki geliyordu:

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

parametre callback:() => UnitUnit döndüren bir sıfır parametreli fonksiyonudur. Sen yapmalıdır çağıracağı isme göre parametre (Unit olarak değerlendirilen bir şey):

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

Ve bu aşağıya çekildi, çünkü? –

İlgili konular