📜  Clojure-循环(1)

📅  最后修改于: 2023-12-03 14:40:06.649000             🧑  作者: Mango

Clojure循环

Clojure是一种基于JVM的Lisp方言,具有函数式编程的特征。在Clojure中,循环是一种控制流程,通过循环我们可以迭代执行语句或代码块。Clojure有许多种循环,每个循环都适用于不同的用途。

for循环

for循环是Clojure中最常见的循环方式之一。for循环语法如下:

(for [binding-seq-1 expr-1
      binding-seq-2 expr-2
      ...
      :while test-expr-1
      :when test-expr-2]
  exprs)

其中,binding-seq定义了一个以指定变量的值为迭代器的序列。在每次迭代中,根据binding-seq中的变量的值,执行exprs。for循环的执行被视为一个表达式,因此会返回最后一个表达式的值。

这是一个计算1-10之和的例子:

(let [sum (for [i (range 1 11)] i)]
  (reduce + sum))

上述代码使用了range函数生成一个数字序列,for循环迭代该序列计算1-10之和。

while循环

while循环是Clojure中另一种常用的循环方式。while循环的语法如下:

(while test-expr body-expr)

其中,test-expr定义了一个布尔表达式,用于测试一个条件语句。只有在测试表达式返回真时,body-expr才会执行,并且这个过程一直执行,直到测试表达式返回假为止。

这是一个计算n的阶乘的例子:

(defn factorial [n]
  (let [result 1]
    (while (> n 0)
      (do
        (set! result (* result n))
        (set! n (- n 1))))
    result))

上述代码使用while循环来计算输入数字n的阶乘。

doseq循环

doseq循环在Clojure程序员之间也很常见。doseq循环的语法如下:

(doseq [binding-seq expr]
  body-expr)

其中,binding-seq定义了一个以指定变量的值为迭代器的序列。在每次迭代中,根据binding-seq中的变量的值,执行body-expr

这是一个打印列表中所有元素的例子:

(doseq [item '(1 2 3 4)]
  (println item))

上述代码使用doseq循环在控制台打印列表'(1 2 3 4)中的所有元素。

loop-recur循环

loop-recur循环在Clojure中也很流行,特别是在递归的情况下。loop-recur循环的语法如下:

(loop [bindings*]
  (if test-expr
    (recur exprs*)
    exprs*))

其中,bindings*是一个可选的绑定序列,用于将循环变量的值绑定到一个初始值上。test-expr是一个布尔测试表达式,一旦为假就会退出循环。exprs*是一个可选的表达式序列,用于计算循环变量的新值。

这是一个打印斐波那契数列的例子:

(defn fib [n]
  (loop [x 0 y 1 cnt n]
    (if (> cnt 0)
      (recur y (+ x y) (- cnt 1))
      x)))

上述代码使用loop-recur循环来计算第n项斐波那契数字。

Conclusion

Clojure在循环方面提供了多个功能强大的选项。在选择循环方式时,需要考虑到程序的需求和性能。使用正确的循环方式可以提高程序的逻辑性和可读性。