如何在Clojure中每行打印一个数字列表?

13

我该如何在10行上打印一个长度为n(比如10)的数字列表?我刚学习了循环和递归,但似乎无法将副作用(println i)与循环形式中的(recur (+ i 1))结合起来。

要非常清楚:我希望输出像这���:

1
2
3
4
5
6
7
8
9
10

当 n 为 10 时。

5个回答

16
你可以使用doseq来实现这个,它的作用是在迭代涉及副作用时使用。
(doseq [i (range 10)]
   (println i))

你可以像提到的那样使用map,但这将产生一个充满nil的序列,这既不符合惯用法,也浪费资源。而doseq并不是lazy的,所以没有必要用doall来强制执行。


1
这将打印数字0到9;在println中使用(inc i),如下面的其他答案所示,会得到1到10。 - Roger
1
改为 (range 1 11) 而不是使用 inc。 - Hamza Yerlikaya

11

我建议使用dotimes进行这种简单的循环:

(dotimes [i 10]
  (println (inc i)))

请注意dotimes是非延迟的,因此它适用于像println这样会引起副作用的事情。


3

使用循环/递归:

(loop [i 1]
  (when (<= i 10)
    (println i)
    (recur (inc i))))

然而,更符合Clojure的惯用语(即更“Clojuristic”)的方法是在1..10的数字上映射println函数。但是由于map返回一个惰性序列,您必须使用doall强制其进行评估
(doall (map println (range 1 (inc 10))))

4
事实上,在这种情况下,使用doseq(或dotimes)更为惯用,因为它涉及到副作用。只有在对返回值感兴趣时才应该使用map。否则,您很容易被延迟计算所困扰。 - kotarak
这段编程代码的翻译是: (dotimes [i 10] (println i)) 谢谢!我在阅读《实用Clojure》第3章,到了第14章会记得这个代码的。:-) - Roger

0

为了全面起见,您也可以使用map来完成:

(doseq (map #(println %) (range 10))

0

如果你只想在屏幕上打印输出,你也可以在进入条件之前简单地放置一个(println i)

(loop [i 0]
  (println i)
  (if (< i 10)
    (recur (inc i))
    (println "done!")))

输出将会每行一个数字。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接