我正在学习Clojure并尝试使用递归函数在列表上循环。我设法一直向下移动嵌套的递归调用,但是当它开始重新启动时我有一个java.lang.NullPointerException。我真的无法弄明白为什么。
我的代码很简单,有一些详细的打印:
(defn parse-list-metadata
[l]
(cond
(empty? l) (println "empty list should never happen")
(== (count l) 1) (str "end of recursion, l=" l)
:else ((println "going deeper, size=" (count l) ", l=" l)
(println (parse-list-metadata (rest l)))
(println "going back up")
)))
结果是:
=> (parse-list-metadata '(1 2 3 4))
going deeper, size= 4 , l= (1 2 3 4)
going deeper, size= 3 , l= (2 3 4)
going deeper, size= 2 , l= (3 4)
end of recursion, l=(4)
going back up
NullPointerException clj-l8metadata.core/parse-list-metadata (form-init896211890420472487.clj:8)
它一直到大小为1的列表但是在返回最嵌套的调用之后,我得到了NullPointerException。我希望有些打印的nil值作为println返回nil,但我真的无法理解我在这里缺少的东西。
我知道还有其他方法可以做到这一点(doseq,recur ...)但我真的很想了解这里发生的事情!
你知道我做错了什么吗?
编辑:我知道NullPointerException是什么,但是Leiningen Clojure REPL对于堆栈的信息量不大。此外,Java中没有变量,因此很难弄清楚如何最终得到NullPointerException。实际上,这是由于我的调试打印,我放在Clojure期望的功能。正如接受的答案所暗示的那样,包裹do
成了伎俩。所以它不是What is a NullPointerException, and how do I fix it? 的副本
答案 0 :(得分:2)
您的问题出在:else
子句中,您需要在第一个左括号后面加do
。您正在获取空指针异常,因为您尝试将(println "going deeper, size=" (count l) ", l=" l)
的结果作为函数调用,但该表达式的结果为nil
。