[英]java.lang.StackOverflowError in clojure tail recursion
I encountered the StackOverflowError for the following code: 我遇到以下代码的StackOverflowError:
(defn recursive-reverse
([coll] (recursive-reverse [coll nil]))
([coll acc]
(if (= coll '()) acc
(recur (rest coll) (cons (first coll) acc)))))
though using loop would make it work: 尽管使用循环会使它工作:
(defn recursive-reverse [lst]
(loop [coll lst acc nil]
(if (= coll '()) acc
(recur (rest coll) (cons (first coll) acc)))))
What goes wrong with the prior code without loop? 没有循环的先前代码出了什么问题?
Your bug is here: 你的错误在这里:
([coll] (recursive-reverse [coll nil]))
You're calling recursive-reverse
with one argument (a vector). 你用一个参数(向量)调用recursive-reverse
。 This calls the same argument list of the function, so it does it recursively and creates a stack frame every time. 这会调用函数的相同参数列表,因此它会递归执行并每次创建一个堆栈帧。
Change it to: 将其更改为:
([coll] (recursive-reverse coll nil))
and you should be right. 你应该是对的。
(Also, separate issue, but I would generally do checking for nil
rather than '()
and using next
rather than rest
. I don't think it has any real advantage in terms of performance or anything, but it seems cleaner to me.) (另外,单独的问题,但我通常会检查nil
而不是'()
并使用next
而不是rest
。我认为它在性能或任何方面都没有任何真正的优势,但它对我来说似乎更清晰。 )
This worked for me: 这对我有用:
(defn recursive-reverse
([coll] (recursive-reverse coll nil))
([coll acc]
(if (= coll '()) acc
(recur (rest coll) (cons (first coll) acc)))))
You passed the arguments to recursive-reverse
inside a couple of unnecessary brackets, that's all. 你将参数传递给了几个不必要的括号中的recursive-reverse
,这就是全部。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.