Recursion 与Clojure和Clojure一起递归,为勇敢和真实的人
我正在努力学习用这本书编程(CFTBAT)。在速成课程的最后,作者让我们写一个小程序来说明Clojure中的循环。为了解释程序的循环和递归部分,作者使用Recursion 与Clojure和Clojure一起递归,为勇敢和真实的人,recursion,clojure,Recursion,Clojure,我正在努力学习用这本书编程(CFTBAT)。在速成课程的最后,作者让我们写一个小程序来说明Clojure中的循环。为了解释程序的循环和递归部分,作者使用loop编写了一个较小的示例,然后展示了用普通函数定义替换loop的可能性 这是一个我无法理解的普通函数定义示例。代码如下: (defn递归打印机 ([] (递归打印机(0)) ([迭代] (println迭代) (如果(>迭代3) (打印“再见!”) (递归打印机(包括迭代(()()))) (递归打印机) 我不理解代码,因为我看不到函数递归打
loop
编写了一个较小的示例,然后展示了用普通函数定义替换loop
的可能性
这是一个我无法理解的普通函数定义示例。代码如下:
(defn递归打印机
([]
(递归打印机(0))
([迭代]
(println迭代)
(如果(>迭代3)
(打印“再见!”)
(递归打印机(包括迭代(()())))
(递归打印机)
我不理解代码,因为我看不到函数递归打印机的参数在哪里。在Clojure中,函数的参数应该放在括号中,函数体应该放在括号中。因此,在本例中,参数将是一个空参数[]
和迭代
。但是为什么它们也被放在括号中呢
什么是(递归打印机0)
它是一个函数调用,函数在其中调用自己吗
如果有人能向我解释这段代码是如何工作的,我将不胜感激。我们可以放弃零算术:
(defn recursive-printer [iteration]
(println iteration)
(if (> iteration 3)
(println "Bye!")
(recursive-printer (inc iteration))))
。。。并使用显式0
参数调用函数:
(recursive-printer 0)
0
1
2
3
4
Bye!
=> nil
这让我们可以专注于递归。由于递归调用是最后一件事(在尾部位置),因此我们可以使用recur
:
(defn recursive-printer [iteration]
(println iteration)
(if (> iteration 3)
(println "Bye!")
(recur (inc iteration))))
。。。具有完全相同的效果
我认为,额外的算术只是把事情弄糊涂了 在clojure中,您可以定义一个函数,使其可以接受不同数量的
论据
(defn foo []
....)
是一个不带参数的函数。它的名字是这样的
(foo)
(defn foo [x]
...)
是一个接受1个参数的函数。它可以被称为
(foo :a)
但有时,您可能需要定义一个取0或1的函数
论点要做到这一点,您需要使用稍微不同的格式
(defn foo
([] ;no argument form
...)
([x] ;single argument form
...))
一个常见的习惯用法是在递归函数定义中使用零参数形式
并将单个“累加器”参数形式作为
功能。所以,看看你的例子,你有
(defn recursive-printer
([] ; zero argument form
(recursive-printer 0))
([iteration] ; 1 argument form
(println iteration)
(if (> iteration 3)
(println "Bye!")
(recursive-printer (inc iteration)))))
(recursive-printer)
调用(递归打印机)时,它调用第一个表单(零参数)
形式)。该表单依次调用单参数为0的函数。这
调用第二种形式
第二个表单首先打印参数,然后测试它是否正确
大于3,在第一次调用中它不是0,因此它执行
'else'语句,该语句使用新参数执行递归调用,新参数是
当前参数增加了1。现在你的论点是1,它被打印出来了
出来测试仍然为false,因为1不大于3,因此再次调用该函数
论点增加了1,即2。在这个调用中,2被打印,测试被取消
仍然不大于3,因此将使用参数再次调用该函数
增加到3。在这个调用中,打印了3,并且测试仍然不是>3,因此
参数增加到4,并再次调用函数,以4作为
论点打印值4,但这次4大于3,因此字符串“Bye”为
已打印,由于这是终止条件,因此不需要进一步的递归调用
make,堆栈展开,函数终止 有两个不同的参数列表。一个是[]
,用代码处理调用时没有参数的情况,另一个是[迭代]
,处理调用时只有一个参数的情况。顺便说一句,由于这本书是在线的,所以有一个链接可能没什么坏处——网络版不是逐页定向的,所以“第63页”对经常使用它的人没有帮助。请参阅第3章“Arity重载”:@CharlesDuffy我编辑了这个问题以添加链接。谢谢,我错过了算术重载!因此,如果在没有参数的情况下调用问题,函数将使用参数(0)调用自身,并将此参数加入到迭代
中,直到它达到4?这是完全正确的。我认为作者想展示一个不使用循环
或递归
的递归示例。