【发布时间】:2011-09-25 03:06:13
【问题描述】:
如何在 10 行上打印一个包含 n 个(例如 10 个)数字的列表?我刚刚了解了循环和递归,但似乎无法将副作用 (println i) 与 (recur (+ i 1)) 以循环形式结合起来。
非常清楚:我想要这样的输出:
1
2
3
4
5
6
7
8
9
10
当 n 为 10 时。
【问题讨论】:
标签: loops printing clojure println
如何在 10 行上打印一个包含 n 个(例如 10 个)数字的列表?我刚刚了解了循环和递归,但似乎无法将副作用 (println i) 与 (recur (+ i 1)) 以循环形式结合起来。
非常清楚:我想要这样的输出:
1
2
3
4
5
6
7
8
9
10
当 n 为 10 时。
【问题讨论】:
标签: loops printing clojure println
您可以为此使用doseq,这意味着在迭代涉及副作用时使用,
(doseq [i (range 10)]
(println i))
你可以使用 map 指出,但这会产生一个充满 nil 的序列,这既不惯用又浪费资源,doseq 也不是懒惰的,所以不需要用 doall 强制它。
【讨论】:
对于这种简单的循环,我建议 dotimes:
(dotimes [i 10]
(println (inc i)))
请注意,dotimes 是非惰性的,因此它适用于像 println 这样会导致副作用的东西。
【讨论】:
带循环/递归:
(loop [i 1]
(when (<= i 10)
(println i)
(recur (inc i))))
但是,map 函数 println 比 1..10 中的数字更惯用(阅读:更多“Clojuristic”)。但是因为map返回的是惰性序列,所以必须force its evaluation with doall:
(doall (map println (range 1 (inc 10))))
【讨论】:
doseq(或dotimes)更为惯用,因为这都是关于副作用的。 map 只有在您对返回值感兴趣时才应使用。否则你很容易被懒惰抓住。
为了全面起见,您也可以使用地图:
(doseq (map #(println %) (range 10))
【讨论】:
如果您只想在屏幕上打印输出,您也可以在输入条件之前简单地输入(println i):
(loop [i 0]
(println i)
(if (< i 10)
(recur (inc i))
(println "done!")))
每行输出一个数字。
【讨论】: