操纵Clojure关闭?

时间:2013-11-21 01:56:02

标签: clojure closures

我是Clojure的新手,我正在创建一个简单的银行账户函数,它返回一个闭包。我已经弄清楚如何初始化变量,但我似乎无法弄清楚如何操纵平衡。我想创建一个:撤回和:存款来履行各自的职能,但我似乎无法弄清楚如何。

(defn account 
  [name initial-balance password]
  (fn [a & args] 
    (condp = a
      :name name
      :balance initial-balance
      :authenticate (= password (first args)))))

2 个答案:

答案 0 :(得分:3)

Clojure成语通常会阻止可变状态。当你想改变像你的银行账户余额这样的东西时,通常的做法是使用线程安全的atom。这是一个例子:

(defn account 
  [name initial-balance password]
  (let [balance (atom initial-balance)]
    (fn [a & args] 
      (case a
        :name name
        :balance @balance
        :deposit (swap! balance + (first args))
        :withdraw (swap! balance - (first args))
        :authenticate (= password (first args))))))

答案 1 :(得分:2)

这是另一种仍然将帐户表示为闭包但不会改变balance的方法。相反,depositwithdraw会返回新的帐户关闭。

(defn account
  [name balance password]
  (fn [msg & args]
    (case msg
      :name name
      :balance balance
      :deposit (account name (- balance (first args)) password)
      :withdraw (account name (+ balance (first args)) password)
      :authenticate (= password (first args)))))

例如(person :deposit 50)会返回一个新的关闭,而不是新的余额,您需要通过:balance来电/消息来跟进,以查看结果余额是什么。

(def person (account "name" 100 "password"))

(person :deposit 50) ; returns a new closure
;=>  #<user$account$fn__85647 user$account$fn__85647@884327>

(person :balance) ; our original `person` still has its original balance
;=> 100

((person :deposit 50) :balance) ; but a new closure can have a new balance
;=> 150