Clojure关闭

时间:2013-02-14 12:32:46

标签: clojure

有一天,我试图在Clojure中提出一个关闭的例子。我想出了以前见过的例子,认为这是合适的。

唉,我被告知这不是一个好人,我应该提供一些东西。

任何人都能解释一下吗?

(defn pow [x n] (apply * (repeat x n)))
(defn sq [y] (pow y 2))
(defn qb [y] (pow y 3))

4 个答案:

答案 0 :(得分:21)

闭包是一个可以在其自己的作用域之外访问某个命名值/变量的函数,因此从函数创建时围绕该函数的更高范围(这将排除函数中创建的函数参数和本地命名值)。您的示例不符合条件,因为每个函数只使用自己作用域中的命名值。

示例:

(def foo 
  (let [counter (atom 0)]
    (fn [] (do (swap! counter inc) @counter))))

(foo) ;;=> 1
(foo) ;;=> 2
(foo) ;;=> 3, etc

现在foo是一个返回其范围之外的原子值的函数。因为函数仍然保存对该原子的引用,只要需要foo,原子就不会被垃圾收集。

答案 1 :(得分:18)

返回函数的函数,即高阶函数是闭包的好例子。

(defn pow [n]
   (fn [x] (apply * (repeat n x))))

(def sq (pow 2))
(def qb (pow 3))

答案 2 :(得分:5)

关闭的另一个例子。有两个函数共享相同的环境(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

答案 3 :(得分:1)

我希望每次都能设置一些常量值。

(def myran 
  (let [constrand (rand)]
    (fn [n] (* n constrand))))


(myran 3)
2.7124521745892096
(myran 1)
0.9041507248630699
(myran 3)
2.7124521745892096

这只会为"约束"设置一个值。一旦。这是一个非常人为的例子,但我希望能够做到这样的事情:

JavaScript: The Good Parts

来自:JavaScript: The Good Parts