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