在Clojure中编写一个get-and-set函数是否有更惯用/可读的方式:
(def the-ref (ref {}))
(defn get-and-set [new-value]
(dosync
(let [old-value @the-ref]
(do
(ref-set the-ref new-value)
old-value))))
答案 0 :(得分:2)
对于简单的情况,我倾向于看到这个操作直接使用而不是包含在函数中:
hello.core> (dosync (some-work @the-ref) (ref-set the-ref 5))
5
在这种情况下, dosync
通常用作您正在寻找的包装。在dosync
内这很重要,因为dosync与其他事务很好地组合,并使事务的边界可见。如果你处于一个包装函数可以完全封装ref的所有引用的位置,那么refs可能不是最好的工具。
参考的典型用法可能看起来更多:
(dosync (some-work @the-ref @the-other-ref) (ref-set the-ref @the-other-ref))
需要包装它很少,因为当使用ref时,它们通常用于多个ref的组中,因为手头的问题需要协调的更改。在它们只是一个值的情况下,原子更常见。