操作Clojure闭包



我是Clojure的新手,正在创建一个返回闭包的简单银行账户函数。我已经想好了如何初始化变量,但似乎不知道如何操作平衡。我想创建一个:取款和:存款来执行它们各自的功能,但我似乎不知道如何实现。

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

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))))))

这里有另一种方法,它仍然将帐户表示为闭包,但不会改变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

最新更新