gpt4 book ai didi

java - Clojure 银行账户汇款示例

转载 作者:行者123 更新时间:2023-12-01 20:54:36 25 4
gpt4 key购买 nike

我是 clojure 的新手,我正在尝试实现经典并发示例,即银行帐户转账。我想使用事务内存来实现它。

这是一个java示例

static class Account {
private double balance;

public synchronized void withdraw(double value) {
balance -= value;
}

public synchronized void deposit(double value) {
balance += value;
}
}

static synchronized void transfer(Account from, Account to, double amount) {
from.withdraw(amount);
to.deposit(amount);
}

不确定我的实现,但它似乎有效。

这是我在 clojure 中的代码

(deftype Account [balance])

(def account1 (Account. (ref 100)))
(def account2 (Account. (ref 100)))

(defn print-accs []
(println " account 1 => " (deref (.balance account1))
" account 2 => " (deref (.balance account2))))

(defn transfer [from to amount]
(dosync
(alter (.balance from) - amount)
(alter (.balance to) + amount)))

(print-accs) ; 100 100

(transfer account1 account2 10)

(print-accs) ; 90 110

这是使用事务内存或正确实现银行账户转账的正确示例吗?我在字段中使用的 ref 是否正确,还是应该将其用于整个 Account 实例?

最佳答案

你不需要deftype,但除此之外它看起来不错。我会像这样简化一下:

(def account1 (ref 100))
(def account2 (ref 100))

(defn print-accs []
(println " account 1 => " @account1
" account 2 => " @account2 ))

(defn transfer [from to amount]
(dosync
(alter account1 - amount)
(alter account2 + amount)))

(print-accs) ; 100 100

(transfer account1 account2 10)

(print-accs) ; 90 110

我建议的一件事是 review The Clojure Cheatsheet并始终保持浏览器选项卡打开。这些链接可提供有关 ClojureDocs.org 的更多详细信息,such as that for dosync 。享受吧!

更新

对于帐户余额之类的单个值,将余额包装在 Account 记录中没有多大意义。如果您想创建一组具有相同字段的记录,您可能需要 defrecord:

(defrecord Account [name balance])

大多数应用程序一开始都使用普通 map ,例如

(def joe-acct (ref {:name "Joe" :balance 100.00})

因为它简单且灵活。稍后,如果您想为始终包含名称和余额的 map 提供类型名称,您可以切换到

(defrecord Account [name balance])
(def joe-acct (ref (Account. "Joe" 100.00)))

deftype 被认为是“较低级别”,现在很少使用。请参阅:

关于java - Clojure 银行账户汇款示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42565492/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com