clojure-koans:dosync里面吗?

时间:2016-09-06 03:29:54

标签: clojure

当我遇到一个有趣的clojure koans in the refs section时,我正在{{3}}工作:

(= "better" (do
      (dosync (ref-set the-world "better"))
      @the-world))

我将其替换为:

(= "better" (dosync (ref-set the-world "better") @the-world))

达到同样的效果。

两者之间有什么有意义的区别吗?为什么公案创建者选择第一个?

1 个答案:

答案 0 :(得分:3)

不同之处在于,您在事务内部或外部deref(读取)该值。如果deref是“transaction”(dosync)的一部分,那么你得到的值肯定是你写的那个,因为它是一个操作的全部内容。

对于这个例子,明显的效果当然是相同的,因为你的参考不能同时工作。但是,如果你还有别的东西敲打它,它看起来像这样:

user=> (def the-world (ref nil))
#'user/the-world
user=> (def disruptor (future (loop [] (dosync (ref-set the-world 0)) (recur))))
#'user/disruptor
user=> @the-world
0
user=> (dosync (ref-set the-world 1) @the-world)
1
user=> (dosync (ref-set the-world 1) @the-world)
1
user=> (do (dosync (ref-set the-world 1)) @the-world)
0
user=> (do (dosync (ref-set the-world 1)) @the-world)
0

disruptor重复地在后台线程中将值设置为0。因此,交易中/交易之外现在很重要。