编写您编写的Java for 循环的Clojure 方法是首先考虑您为什么要循环。将 Java 循环移植到 Clojure 有很多选择。在其中进行选择取决于您的目标。
制作十个零的方法
正如 Carcigenicate 所发布的,如果您在一个集合中需要十个零,请考虑:
(repeat 10 0)
这会返回一个sequence – 一个lazy。序列是 Clojure 的核心抽象之一。如果需要通过索引访问十个零,请将它们放在一个向量中:
(vec (repeat 10 0))
或
(into [] (repeat 10 0))
或者,您可以直接在代码中编写向量字面量:
[0 0 0 0 0 0 0 0 0 0]
如果您出于某种原因特别需要一个 Java 数组,那么您可以使用to-array:
(to-array (repeat 10 0))
但请记住the Clojure reference docs on Java interop的建议:
Clojure 支持创建、读取和修改 Java 数组 [但] 建议您限制使用数组以与需要它们作为参数或将它们用作返回值的 Java 库进行互操作。
这些文档列出了一些用于处理 Java 数组的函数,主要用于 Java 互操作或“支持突变或更高性能的操作”。在几乎所有情况下,Clojurists 只使用向量。
在 Clojure 中循环
如果您要做的不是产生十个零,该怎么办? Clojure 的“循环”方式取决于您的需要。
你可能需要递归,Clojure 有 loop/recur:
(loop [x 10]
(when-not (= x 0)
(recur (- x 2))))
您可能需要为某些集合中的每个值计算一个值:
(for [x coll])
(calculate-y x))
您可能需要遍历多个集合,类似于 Java 中的嵌套循环:
(for [x ['a 'b 'c]
y [1 2 3]]
(foo x y))
如果您只需要多次产生副作用,repeatedly 就是您的果酱:
(repeatedly 10 some-fn)
如果您需要为集合中的每个值产生副作用,请尝试doseq:
(doseq [x coll]
(do-some-side-effect! x))
如果您需要对整数范围产生副作用,您可以像这样使用doseq:
(doseq [x (range 10)]
(do-something! x))
...但是dotimes 就像带有内置range 的doseq:
(dotimes [x 9]
(do-something! x))
比那些循环构造更常见的是 Clojure 函数,它为集合中的每个元素生成一个值,例如 map 及其亲属,或者出于特殊目的迭代集合(例如 filter 和 @987654349 @) 或创建一些新值或集合(如reduce)。