Это закрытие? Если да, то почему?

Готовя ответ на другой вопрос ], я создал его для себя. Рассмотрим следующую короткую программу.

(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", но изменяется в слушателе. В моем более раннем опыте работы с такими языками, как Паскаль, я считал, что «counter» передается по ссылке. Так ли это здесь или это пример закрытия? Что-нибудь еще?

Спасибо за помощь.

6
задан Community 23 May 2017 в 11:47
поделиться