【问题标题】:How to do a for-loop in Clojure?如何在 Clojure 中进行 for 循环?
【发布时间】:2013-03-10 09:46:35
【问题描述】:

我正在学习一些 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)))

【问题讨论】:

标签: clojure quil


【解决方案1】:

您所寻找的所有方法基本上都是使用序列,其中循环是关于执行特定次数的事情。 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)))

【讨论】:

    【解决方案2】:

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

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

    不过,通常情况下,我会发现自己使用以下方法之一:

    • (dotimes [i num-sides] ....) - 做某事特定次数
    • (doseq [x some-sequence] ....) - 为序列中的每个元素做一些事情
    • (for [i (range n)] ...) - 构造一个包含 n 个元素的列表

    【讨论】:

    • 如何让宏更 C-ish,这样我们就可以做到:(for-loop [ [i 1 j 1] (&lt; i 10) [i (inc i) j (* j i)] ] .....)
    • @Ankur 有趣的想法....我自己不需要,但可以看到一些用例的价值。
    【解决方案3】:

    也许这有点学术,但我喜欢使用 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)))
    

    【讨论】:

    • 但是for 在这种情况下不必要地构造了一个惰性序列。如果您不需要输出序列,如本例所示,您可以使用doseq 执行相同的操作——使用相同的绑定技巧。只需将上述代码中的for 替换为doseq。在许多情况下,生成额外序列的成本可以忽略不计,因此doseq 的唯一优势是它向读者传达您没有尝试创建序列。但是,在某些情况下,创建不必要序列的成本可能会影响性能。
    【解决方案4】:

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

    (doseq [i (range 0 num-sides)]
      (ellipse (cos (* theta i)) 
               (sin (* theta i)) 
               poly-size 
               poly-size))
    

    【讨论】:

      猜你喜欢
      • 2012-04-16
      • 1970-01-01
      • 1970-01-01
      • 2016-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多