clojure 尾递归中的 java.lang.StackOverflowError
我遇到了以下代码的 StackOverflowError:
(defn recursive-reverse
([coll] (recursive-reverse [coll nil]))
([coll acc]
(if (= coll '()) acc
(recur (rest coll) (cons (first coll) acc)))))
尽管使用循环可以使其工作:
(defn recursive-reverse [lst]
(loop [coll lst acc nil]
(if (= coll '()) acc
(recur (rest coll) (cons (first coll) acc)))))
没有循环的先前代码出了什么问题?
I encountered the StackOverflowError for the following code:
(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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的错误在这里:
您正在使用一个参数(一个向量)调用
recursive-reverse
。这会调用函数的相同参数列表,因此它会递归执行并每次都会创建一个堆栈帧。将其更改为:
你应该是对的。
(另外,单独的问题,但我通常会检查
nil
而不是'()
并使用next
而不是rest< /code>。我认为它在性能或其他方面没有任何真正的优势,但对我来说似乎更干净。)
Your bug is here:
You're calling
recursive-reverse
with one argument (a vector). This calls the same argument list of the function, so it does it recursively and creates a stack frame every time.Change it to:
and you should be right.
(Also, separate issue, but I would generally do checking for
nil
rather than'()
and usingnext
rather thanrest
. I don't think it has any real advantage in terms of performance or anything, but it seems cleaner to me.)这对我有用:
您将参数传递给了几个不必要的括号内的
recursive-reverse
,仅此而已。This worked for me:
You passed the arguments to
recursive-reverse
inside a couple of unnecessary brackets, that's all.