clojure中的惯用惰性原子

时间:2015-04-27 14:41:58

标签: clojure atomic lazy-sequences

我正在玩clojure中的原子。我有atom指向lazy-seq。在另一段代码中,我想将原子的值更新为对序列执行next的结果,但假设swap!reset!都返回更新的值,则执行永远不会结束。 我发现我总是可以在do语句中将调用包装到swap!reset!,然后返回nil,但我想知道这是一个惯用的或者是否有替代解决方案这样做。

不会终止:

(def x (atom (range)))
(swap! x next)

终止

(def x (atom (range)))
(do (swap! x next) nil)
(first @x) ;1
(do (swap! x next) nil)
(first @x) ;2

2 个答案:

答案 0 :(得分:8)

这里的问题不是Clojure,而是你使用的repl。对swap!的调用工作得很好,就是repl试图打印出结果而不能,因为序列永远不会结束。您可以通过(set! *print-length* 10)设置Clojure内置repl打印的项目数。但是,如果您有其他执行不同打印逻辑的REPL中间件,这并不总是有效。

关于“这样做的惯用方法是什么”,我会给你两个选择:

  1. 在返回某些内容的函数中将您的调用传递给swap! 不同。
  2. 或者,在上面的用例中,在atom中放入一个整数,然后使用(swap! x inc)来获取下一个整数。

答案 1 :(得分:1)

好吧,你可以把掉掉!首先:

(def x (atom (range)))
(first (swap! x next))
(first (swap! x next))

但是我不确定你为什么要包装无限列表然后每次只使用第一个值。看起来这样会更简单并产生相同的结果:

(def x (atom 0))
(swap! x inc)
(swap! x inc)