爲什麼這一點的Clojure代碼:Clojure的不斷和地圖功能
user=> (map (constantly (println "Loop it.")) (range 0 3))
產量輸出:
Loop it.
(nil nil nil)
我希望它打印出「循環播放」三倍側三次評估功能的效果。
爲什麼這一點的Clojure代碼:Clojure的不斷和地圖功能
user=> (map (constantly (println "Loop it.")) (range 0 3))
產量輸出:
Loop it.
(nil nil nil)
我希望它打印出「循環播放」三倍側三次評估功能的效果。
constantly
不評估其參數多次。這是一個函數,而不是一個宏,因此在運行constantly
之前,參數只被計算一次。所有constantly
確實是需要的(評價)的說法,並返回每次被稱爲時間返回給定值的函數(無需重新評估什麼,因爲,正如我所說,constantly
運行之前的說法已經被評估)。
如果您只想對該範圍內的每個元素調用(println "Loop it")
,則應該將其作爲映射函數傳遞,以代替constantly
。請注意,您實際上必須將其作爲函數傳遞,而不是評估表達式。
你可以通過USIG repeatedly和lambda表達式靠近你的意圖的行爲。
例如:
(repeatedly 3 #(println "Loop it"))
除非你在REPL,這需要由一個dorun
或類似的包圍。 repeatedly
是懶惰的。
由於sepp2k正確地指出constantly
是一個函數,所以它的參數將只計算一次。
慣用的方式來實現,你在這裏做什麼是使用doseq
:
(doseq [i (range 0 3)]
(println "Loop it."))
或可替代dotimes
(因爲你實際上並沒有使用其在該特定情況下多了幾分簡潔高效)由range
產生的序列:
(dotimes [i 3]
(println "Loop it."))
這些解決方案的兩者都是非延遲,這可能是你想要什麼,如果你是剛剛運行的副作用,一些代碼。
瞥源。這看起來像贏家。 – Mike 2012-07-23 13:10:45
試圖不斷使用,以避免顯式傳遞我不需要的參數。雖然會解決這個問題。 – Mike 2012-07-23 13:18:39
請注意,如果你只是想副作用,你應該使用'doseq'或'dotimes'。由於'map'是懶惰的,除非你用'doall'或'dorun'強制執行,否則你不會得到你想要的結果。 – 2012-07-23 15:18:39