2011-01-26 15 views
6

another question'a bir yanıt hazırlarken kendim için bir tane oluşturdum. Aşağıdaki kısa programı dikkate alın. aksiyon dinleyici de Bu bir kapatma mı? Öyleyse neden?

(ns net.dneclark.JFrameAndTimerDemo 
    (:import (javax.swing JLabel JButton JPanel JFrame Timer)) 
    (:gen-class)) 

(defn timer-action [label counter] 
(proxy [java.awt.event.ActionListener] [] 
    (actionPerformed 
    [e] 
     (.setText label (str "Counter: " (swap! counter inc)))))) 

(defn timer-fn [] 
    (let [counter (atom 0) 
     label (JLabel. "Counter: 0") 
     timer (Timer. 1000 (timer-action label counter)) 
     panel (doto (JPanel.) 
       (.add label))] 
    (.start timer) 
    (doto (JFrame. "Timer App") 
     (.setContentPane panel) 
     (.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE) 
     (.setLocation 300 300) 
     (.setSize 200 200) 
     (.setVisible true)))) 

(defn -main [] 
    (timer-fn)) 

, 'zamanlayıcı aksiyon', 'karşı' bağımsız değişkenin değeri değiştirilir. Gerçek değişken, 'timer-fn' işlevinde bildirilir, ancak dinleyicide değiştirilir. Pascal gibi dillerle ilgili daha önceki deneyimlerime göre, referansla geçilecek 'sayacı' düşünürdüm. Buradaki durum mu bu yoksa bu bir kapanış örneğidir? Başka bir şey?

Yardımlarınız için teşekkürler.

cevap

3

Evet, bu bir kapanış. İşleyici işlev tanımının sözcüksel içeriği korunur ve daha sonra çağrıldığında, orada "canlı" olan değişkenlere erişebilir ve bunları güncelleyebilir.

Soruyu nasıl yanıtlayacağımı bilmiyorum "neden?" dilin işleyiş biçiminin basitçe ifade edildiğini belirtmekten başka.

+0

Teşekkürler Pointy. Sen bana * nedenini anlattı - işleyicinin sözcüksel içeriğini koruyarak. Başım ağrıyor hala bir şey var. – clartaq

+0

Bunun zor olduğunu düşündüm ama sadece böyle düşün. (...) o zaman ... sözcüksel bir bağlamda (i = 5 ....) gibi bir şey olduğunu söyleyin, sonra 5'in her biri parens içinde. Eğer bir işlevi tanımlarsanız ve bu işlev (fn ....) dışında bir şey kullandığınızda bir kapanışınız vardır, çünkü değişkenlerin ne anlama geldiğini bulmak için işlevin() dışına bakar. – nickik