在准备another question的答案时,我为自己创建了一个答案。考虑以下简短程序。
(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))
在动作监听器'timer-action'中,'counter'参数的值被改变。实际变量在'timer-fn'函数中声明,但在侦听器中被更改。在我之前使用像Pascal这样的语言的经验中,我会认为'counter'可以通过引用传递。这是这种情况还是这个闭包的例子?还有别的吗?
感谢您的帮助。
答案 0 :(得分:3)
是的,这是关闭。处理函数定义的词法上下文被保留,稍后调用它时,它可以访问和更新那里“活”的变量。
我不知道如何回答这个问题,“为什么?”除了指出它只是定义语言的工作方式。