我是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
。相反,deposit
和withdraw
返回一个新的帐户关闭。
(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