Mientras preparaba una respuesta al another question, creé una para mí. Considere el siguiente programa corto.¿Es esto un cierre? Si es así, ¿por qué?
(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))
En el detector de acciones, 'timer-action', se modifica el valor del argumento 'contador'. La variable real se declara en la función 'timer-fn', pero se altera en el oyente. En mi experiencia anterior con idiomas como Pascal, hubiera considerado que el 'contador' se pasa por referencia. ¿Es ese el caso aquí o es este un ejemplo de cierre? ¿Algo más?
Gracias por la ayuda.
Gracias Pointy. Usted * me * dijo por qué - manteniendo el contexto léxico del controlador. Algo que aún me cuesta entender. – clartaq
Pensé que también era difícil, pero solo piense en eso. (...) entonces ... el contexto léxico dice que tienes algo así como (i = 5 ....) entonces yo tengo 5 en cada lugar dentro de los parens. si define una función y esa función usa algo que está fuera de (fn ....) tiene un cierre porque se ve fuera de() de la función para averiguar qué significan las variables. – nickik