📅  最后修改于: 2023-12-03 14:40:06.649000             🧑  作者: Mango
Clojure是一种基于JVM的Lisp方言,具有函数式编程的特征。在Clojure中,循环是一种控制流程,通过循环我们可以迭代执行语句或代码块。Clojure有许多种循环,每个循环都适用于不同的用途。
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循环是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循环在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循环在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项斐波那契数字。
Clojure在循环方面提供了多个功能强大的选项。在选择循环方式时,需要考虑到程序的需求和性能。使用正确的循环方式可以提高程序的逻辑性和可读性。