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'函數中聲明,但在偵聽器中更改。在我以前使用Pascal語言的經驗中,我認爲'counter'是通過引用傳遞的。這是這種情況還是這是關閉的例子?還有別的嗎?
感謝您的幫助。
謝謝Pointy。你*確實*告訴我爲什麼 - 維護處理程序的詞法上下文。我仍然有困難纏着我的頭。 – clartaq
我覺得這很難,但只是想到這一點。 (...)然後......是詞彙語境,表示你有類似的東西(i = 5 ....),那麼我就是每個在parens裏面的地方。如果你定義了一個函數,並且該函數正在使用(fn ....)以外的東西,那麼你有一個閉包,因爲它看起來不在函數的()中,以查明變量的含義。 – nickik