如何在Clojure中解决相互递归函数的名称未定义问题?
解决Clojure中相互递归函数的未定义问题
这个问题在Clojure里挺常见的——因为Clojure是按从上到下的顺序求值的,当你定义f1的时候,f2还没被创建出来,编译器自然找不到它,所以会抛出未定义的错误。既然你已经确认递归逻辑能终止,那只需要解决函数提前声明的问题就行,这里有两种常用方案:
1. 使用declare提前声明函数名(推荐)
declare是Clojure专门用来提前声明符号的工具,它会告诉编译器“后面会有这些函数定义”,这样在定义f1的时候,编译器就不会因为找不到f2而报错了。示例代码如下:
;; 先声明f1和f2的存在 (declare f1 f2) (defn f1 [x] (if (<= x 0) 0 (f2 (- x 1)))) ;; 这里调用f2就不会报错了 (defn f2 [x] (if (<= x 0) 1 (f1 (- x 1)))) ;; 同理调用f1也没问题
这个方法是官方推荐的,代码可读性也最强,是处理相互递归的首选方式。
2. 先用def占位,再重新定义函数
另一种方式是先给f2绑定一个临时值(比如nil),然后定义f1,最后再重新定义f2的实际逻辑。不过这种方式可读性不如declare,一般只在特殊场景下使用:
;; 先给f2绑定一个临时值 (def f2 nil) (defn f1 [x] (if (<= x 0) 0 (f2 (- x 1)))) ;; 重新定义f2的实际逻辑,此时f1已经存在 (defn f2 [x] (if (<= x 0) 1 (f1 (- x 1))))
两种方法都能解决你的问题,优先选第一种就好~
内容的提问来源于stack exchange,提问作者saga
相关产品推荐
相关产品推荐

