【发布时间】:2013-12-15 11:33:57
【问题描述】:
这个 Clojure 代码输出 32,而我期望输出 100。为什么会这样?用计数器制作循环的好方法是什么?
(def t 0)
(for [i (range 100)]
(def t (+ 1 t))
)
(println t)
【问题讨论】:
标签: loops for-loop clojure range
这个 Clojure 代码输出 32,而我期望输出 100。为什么会这样?用计数器制作循环的好方法是什么?
(def t 0)
(for [i (range 100)]
(def t (+ 1 t))
)
(println t)
【问题讨论】:
标签: loops for-loop clojure range
for 计算为惰性序列。由于一种叫做分块的东西,你在这里很幸运,for 被分块成 32 个元素的惰性分区。
您问题中的代码非常不习惯。
在你的情况下,你可以打电话给(println 100)
如果你想循环一个序列以获得一些副作用,那么你可以使用doseq
(doseq [i (range 100)]
(println i))
;; or
(dotimes [i 100]
(println i))
【讨论】:
doseq 正是我所需要的,谢谢!很难从命令式编程语言切换到函数式 Clojure。有没有收集好的惯用代码的来源?
一些注意事项:
这是一种更惯用的方式来获得你想要的东西:
; a more functional way
(def t (reduce + (take 100 (repeat 1))))
(println t)
; a more "stateful" approach
(def t (atom 0))
(doseq [i (range 100)]
(swap! t inc))
(println @t)
【讨论】:
(reduce + 0 ...) == (reduce + ...) 和 (swap! t + 1) == (swap! t inc)。 (根本)并没有改善答案,但我仍然想提一下。 :-)