看起来你的括号是错误的——你if
需要一个else
表格。我怀疑你的意思是这样的:
(defn addall
([] 0)
([& x]
(if (empty? x)
0 ;;; <=== no ')' after 0
(+ (first x) (addall (rest x)))))) ;;; <== extra ')' here
但是即使修复了这个问题,您的代码仍然是错误的:它假定使用多个参数调用它(addall 1 2 3)
-- 但通过向自身传递一个列表来重复 -- (addall [2 3])
。这会导致它陷入没有取得任何进展的循环中,您可以通过添加print
语句来观察:
(defn addall
([] 0)
([& x]
(print (str "new x: " x "\n"))
(if (empty? x)
0 ;;; <=== no ')' after 0
(+ (first x) (addall (rest x))))))
这实际上在我的计算机上产生了段错误!
此外,它有两个基本情况。我建议这样做:
(defn addall
[xs]
(if (empty? xs)
0
(+ (first xs)
(addall (rest xs)))))
用向量调用:
(addall [1 2 3])
或者,如果您想使用可变参数函数,您还需要apply
:
(defn addall
[& x]
(print (str "new x: " x "\n"))
(if (empty? x)
0
(+ (first x)
(apply addall (rest x))))) ;;; <=== apply addall
也就是说,您应该注意 Clojure 没有尾调用优化,这意味着此代码在输入中等大小时会失败。Clojure 鼓励使用loop/recur
内置的序列处理函数。