2011-01-26 19 views
6

Mentre preparavo una risposta allo another question, ne ho creato uno per me stesso. Considera il seguente breve programma.È una chiusura? Se è così, perché?

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

Nel listener di azioni, 'timer-action', il valore dell'argomento 'contatore' viene modificato. La variabile attuale è dichiarata nella funzione 'timer-fn', ma è alterata nell'ascoltatore. Nella mia precedente esperienza con linguaggi come Pascal, avrei considerato il 'contatore' da passare per riferimento. È questo il caso o è un esempio di chiusura? Qualcos'altro?

Grazie per l'aiuto.

risposta

3

Sì, è una chiusura. Il contesto lessicale della definizione della funzione del gestore viene mantenuto e, quando viene invocato, può accedere e aggiornare le variabili che "vivono" lì.

Non sono sicuro di come rispondere alla domanda, "perché?" a parte sottolineare che è semplicemente il modo in cui la lingua viene definita per funzionare.

+0

Grazie a punta. Mi hai * detto * perché - mantenendo il contesto lessicale del conduttore. Qualcosa ho ancora difficoltà a girarmi intorno. – clartaq

+0

Ho pensato che fosse difficile, ma pensaci in questo modo. (...) poi ... il contesto lessicale dice che hai qualcosa come (i = 5 ....) poi io sono 5 ogni dove all'interno dei paren. se si definisce una funzione e quella funzione sta usando qualcosa che io al di fuori di (fn ....) si ha una chiusura perché appare al di fuori della() della funzione per scoprire cosa significano le variabili. – nickik