gpt4 book ai didi

clojure - 在可变参数函数中使用 recur 时出现意外行为

转载 作者:行者123 更新时间:2023-12-04 03:41:53 26 4
gpt4 key购买 nike

我正在为 this 写一个答案挑战,当我需要给递归函数一个可选参数时。我最终得到了一些相当于:

(defn func [a & [b?]]
(if b?
b?
(recur a a)))

我的意图是 b?作为可选参数。如果未提供,则默认为 nil通过解构。

虽然没有运行,但它给了我一个错误:
(func 1)
UnsupportedOperationException nth not supported on this type: Long clojure.lang.RT.nthFrom (RT.java:947)

经过一些调试后,我意识到由于某种原因,rest 参数并不是我所期望的列表,而只是传递的数字!出现错误是因为它试图解构数字。

我可以通过去掉参数列表中的包装器列表来修复它:
(defn func [a & b]
...

但这看起来是错误的。我知道其余参数应该是一个列表,但是 b实际上只是一个数字。如果我使用“未优化”递归,它会按我的预期工作:
(defn func2 [a & [b?]]
(if b?
b?
(func2 a a)))

(func2 1)
=> 1

谁能解释一下这里发生了什么?

最佳答案

这似乎是一个 known difference

; Note that recur can be surprising when using variadic functions.

(defn foo [& args]
(let [[x & more] args]
(prn x)
(if more (recur more) nil)))

(defn bar [& args]
(let [[x & more] args]
(prn x)
(if more (bar more) nil)))

; The key thing to note here is that foo and bar are identical, except
; that foo uses recur and bar uses "normal" recursion. And yet...

user=> (foo :a :b :c)
:a
:b
:c
nil

user=> (bar :a :b :c)
:a
(:b :c)
nil

; The difference arises because recur does not gather variadic/rest args
; into a seq.

这是描述差异的最后一条评论。

关于clojure - 在可变参数函数中使用 recur 时出现意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46228115/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com