我正在玩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
答案 0 :(得分:8)
这里的问题不是Clojure,而是你使用的repl。对swap!
的调用工作得很好,就是repl试图打印出结果而不能,因为序列永远不会结束。您可以通过(set! *print-length* 10)
设置Clojure内置repl打印的项目数。但是,如果您有其他执行不同打印逻辑的REPL中间件,这并不总是有效。
关于“这样做的惯用方法是什么”,我会给你两个选择:
swap!
不同。(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)