有一天,我試圖想出一個關閉Clojure的例子。我想出了以前見過的例子,並認爲它是適當的。Clojure關閉
唉,我被告知它不是一個好的,我應該提供一些東西。
任何人都可以點亮一下嗎?
(defn pow [x n] (apply * (repeat x n)))
(defn sq [y] (pow y 2))
(defn qb [y] (pow y 3))
有一天,我試圖想出一個關閉Clojure的例子。我想出了以前見過的例子,並認爲它是適當的。Clojure關閉
唉,我被告知它不是一個好的,我應該提供一些東西。
任何人都可以點亮一下嗎?
(defn pow [x n] (apply * (repeat x n)))
(defn sq [y] (pow y 2))
(defn qb [y] (pow y 3))
的閉合件是具有訪問範圍之外的一些命名值/變量,因此從圍繞函數創建時更高的範圍的函數(不包括函數參數和內所創建的本地命名值功能)。您的示例不具備資格,因爲每個函數都只使用來自其範圍的命名值。
實施例:
(def foo
(let [counter (atom 0)]
(fn [] (do (swap! counter inc) @counter))))
(foo) ;;=> 1
(foo) ;;=> 2
(foo) ;;=> 3, etc
foo
現在是返回的原子是其範圍之外的值的函數。因爲該函數仍然包含對該原子的引用,所以只要foo
需要,原子就不會被垃圾收集。
函數返回函數,即高階函數是閉包的很好例子。
(defn pow [n]
(fn [x] (apply * (repeat n x))))
(def sq (pow 2))
(def qb (pow 3))
關閉的另一個例子。有兩個共享相同環境的功能(state
)。
(defn create-object [init-state]
(let [state (atom init-state)]
{:getter (fn []
@state)
:setter (fn [new-val]
(reset! state new-val))}))
(defn test-it []
(let [{:keys [setter getter]} (create-object :init-value)]
(println (getter))
(setter :new-value)
(println (getter))))
(test-it)
=> :init-value
:new-value
謝謝,一個很好的例子!) – Eddy 2013-02-16 10:16:26
我想有一些設置每次都要使用的常量值。
(def myran
(let [constrand (rand)]
(fn [n] (* n constrand))))
(myran 3)
2.7124521745892096
(myran 1)
0.9041507248630699
(myran 3)
2.7124521745892096
這將只爲「約束」設置一次值。這是一個很做作的例子,但我希望能夠做一些事情,如:
嗨,所以我的例子將是一個閉合如果我定義的體我的戰俘像你一樣(關閉是永遠f)? – Eddy 2013-02-14 12:54:40
是的,這將是一種描述關閉的方式 – Ankur 2013-02-15 04:25:12
+1優雅的例子! – 2013-05-23 05:37:21