4

我正在学习一些 Clojure,我正在使用 Quil。我想知道如何将 for 循环转换为 Clojure:

这就是我在 Java 或类似语言中的做法:

for ( int i = 0; i < numSides; i++ ) {
    float posX = cos( theta * i );
    float posY = sin( theta * i );
    ellipse( posX, posY, polySize, polySize );
}

我的 Clojure 尝试:

  (let [theta (/ PI num-sides)
        angle (range 0 num-sides)
        pos-x (cos (* theta angle))
        pos-y (sin (* theta angle))]
    (dorun (map #(ellipse % % % %) pos-x pos-y poly-size poly-size)))
4

4 回答 4

7

您寻找的所有方法基本上都是使用序列,其中循环是关于执行特定次数的事情。Clojure 提供dotimes了一定次数的操作:

(dotimes [i 10]
  (println i))

所以你的代码变成了这样:

 (dotimes [i num-sides]
   (let [pos-x (cos (* theta i))
         pos-y (sin (* theta i))]
         (ellipse pos-x pos-y poly-size poly-size)))
于 2013-03-10T09:58:19.027 回答
4

如果你真的想要一个 C 风格的for循环,那么我的clojure-utils库有一个方便的 for-loop 宏,可以让你执行以下操作:

(for-loop [i 0 , (< i num-sides) , (inc i)]
  ... do stuff.....)

但是,通常我会发现自己使用以下方法之一:

  • (dotimes [i num-sides] ....)- 做某事特定次数
  • (doseq [x some-sequence] ....)- 为序列中的每个元素做一些事情
  • (for [i (range n)] ...)- 构造一个包含 n 个元素的列表
于 2013-03-10T10:26:50.503 回答
2

也许这有点学术,但我喜欢使用 Clojure 的“用于理解”来处理这类事情。代码如下所示:

(dorun
  (for [i (range num-sides)
        :let [pos-x (Math/cos (* i theta))
              pos-y (Math/sin (* i theta))]]
    (quil.core/ellipse pos-x pos-y poly-size poly-size)))
于 2013-05-24T20:36:36.190 回答
1

Doseqwithrange通常适用于循环特定数量的值以产生副作用。我将按如下方式实现您的循环:

(doseq [i (range 0 num-sides)]
  (ellipse (cos (* theta i)) 
           (sin (* theta i)) 
           poly-size 
           poly-size))
于 2013-09-26T20:44:20.583 回答