简体   繁体   English

clojure尾递归中的java.lang.StackOverflowError

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM