6
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'함수에서 선언되지만 리스너에서 변경됩니다. 파스칼 같은 언어에 대한 나의 초기 경험에서, 나는 '카운터'가 참조로 전달 될 것이라고 생각했을 것이다. 이 사건이 여기에 해당합니까 아니면 이것이 종결의 한 예입니까? 다른 것?
도움 주셔서 감사합니다.
감사합니다. 왜 핸들러의 어휘 적 맥락을 유지했는지 말해 주었다. 뭔가 머리가 감싸는 데 어려움이 있습니다. – clartaq
나는 그것이 어렵다고 생각했지만 그렇게 생각한다. (...) then ... 어휘 문맥이 당신이 (i = 5 ....와 비슷한 것을 가지고 있다고 말하면, 나는 괄호 안에있는 모든 곳에서 5입니다. 당신이 함수를 정의하고 그 함수가 (fn ....)의 바깥쪽에있는 어떤 것을 사용한다면 함수의 바깥 쪽을보고 변수가 무엇을 의미하는지 알아 내기 때문에 클로저가 있습니다. – nickik