2015-04-27 19 views
4

我在clojure中玩了一下原子。我有一個​​指向lazy-seq。在另一位代碼中,我想將原子的值更新爲序列上的next的結果,但假設swap!reset!都返回更新後的值,執行永遠不會結束。 我發現我總是可以將打電話給swap!,reset!包含在一個do語句中,然後返回nil,但我想知道這是多麼地道,或者是否有替代解決方案來做到這一點。clojure中的慣用惰性原子

不會終止:

(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 

回答

8

這裏的問題是沒有這麼多使用Clojure,但與REPL您使用。對swap!的調用工作正常,這是repl試圖打印出結果,並且因爲序列永遠不會結束,所以它不能結束。您可以通過(set! *print-length* 10)設置Clojure內置版本打印的項目數量。但是如果您有其他執行不同打印邏輯的REPL中間件,這並不總是奏效。

上的「什麼是這樣做的慣用方式」的話題,我願意給你兩個選擇:

  1. 包裝你到swap!呼叫返回不同的東西 的功能。
  2. 或者,在上面的用例中,在原子中放置一個整數,然後使用(swap! x inc)來獲取下一個整數。
+0

謝謝!這給了我的問題的解決方案。我想按照你的第一個選項,在do語句中包裝呼叫應該被認爲是慣用的 – emanjavacas

1

好吧,你可以只合並掉!和第一個:

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

但我不知道爲什麼你想包裝無限列表,然後每次只使用第一個值。看起來這將是簡單,產生相同的結果:

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

感謝您的回答,實際上這是我的代碼的簡化版本。實際上我沒有範圍,只是另一種懶惰seq,其中並不總是下一個值是以前的值加1。 – emanjavacas