这是封闭吗?如果是这样,为什么?

时间:2011-01-26 14:53:34

标签: clojure closures

在准备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'可以通过引用传递。这是这种情况还是这个闭包的例子?还有别的吗?

感谢您的帮助。

1 个答案:

答案 0 :(得分:3)

是的,这是关闭。处理函数定义的词法上下文被保留,稍后调用它时,它可以访问和更新那里“活”的变量。

我不知道如何回答这个问题,“为什么?”除了指出它只是定义语言的工作方式。