List clojure尾部递归中的java.lang.StackOverflower错误
我遇到以下代码的StackOverflower错误:List clojure尾部递归中的java.lang.StackOverflower错误,list,loops,clojure,stack-overflow,reverse,List,Loops,Clojure,Stack Overflow,Reverse,我遇到以下代码的StackOverflower错误: (defn recursive-reverse ([coll] (recursive-reverse [coll nil])) ([coll acc] (if (= coll '()) acc (recur (rest coll) (cons (first coll) acc))))) 尽管使用loop可以让它工作: (defn recursive-reverse [lst] (loop [coll ls
(defn recursive-reverse
([coll] (recursive-reverse [coll nil]))
([coll acc]
(if (= coll '()) acc
(recur (rest coll) (cons (first coll) acc)))))
尽管使用loop可以让它工作:
(defn recursive-reverse [lst]
(loop [coll lst acc nil]
(if (= coll '()) acc
(recur (rest coll) (cons (first coll) acc)))))
以前没有循环的代码出了什么问题?这对我很有用:
(defn recursive-reverse
([coll] (recursive-reverse coll nil))
([coll acc]
(if (= coll '()) acc
(recur (rest coll) (cons (first coll) acc)))))
您在几个不必要的括号内将参数传递给了递归反向,仅此而已。您的错误如下:
([coll] (recursive-reverse [coll nil]))
您正在使用一个参数(向量)调用递归反向
。这将调用函数的同一个参数列表,因此它递归地执行此操作,并每次创建一个堆栈帧
将其更改为:
([coll] (recursive-reverse coll nil))
你应该是对的
(还有一个单独的问题,但我通常会检查nil
而不是”()
,使用next
而不是rest
。我不认为它在性能或任何方面有任何真正的优势,但对我来说它似乎更干净。)(nil?x)
可能比(=x())
快得多,因为编译器只能发出一个字节码操作,所以Java使用的原语null检查。当然,后者相当快,但我怀疑它比前者慢好几倍。碰巧的是,这个优化的nil检查没有实现(还没有实现?),但它是一个合理的优化,最终可能会实现。