Clojure不使用max实现列表求最大值运行报错求解
问题根因
报错是括号使用不符合Clojure语法规则导致的,Clojure中括号首位元素默认是可调用对象(函数、宏等),你代码里两处都把非函数值放到了括号首位,触发了Long/布尔值无法转为可调用对象的错误:
-main函数let块里定义列表的写法错了:L (4 5 10 1)这行,括号里第一个元素是数字4,Clojure会直接尝试执行(4 5 10 1)也就是把4当函数调用,4是Long类型数字,根本不能调用,这就是你看到的报错的直接触发点。定义字面量列表要么用list函数构造,要么加单引号阻止列表被求值,正确写法是L (list 4 5 10 1)或者L '(4 5 10 1)。getLargest函数的cond分支多套了一层括号:第三个判断条件你写的是((> (first L) (getLargest (rest L)))),就算前面列表定义对了,(> ...)跑完只会得到true或者false的布尔值,外面多包的一层括号会让Clojure尝试把这个布尔值当函数调用,一样会报同样的类型错误,把外层多余的括号删掉就行。
额外提个优化点:你现在的递归写法会重复计算,判断条件里算一次尾部列表的最大值,else分支又要算一次,列表长了性能会很差,可以用let把递归得到的尾部最大值存下来,只算一次。
修正后的完整代码
(ns iotest.core (:gen-class)) (defn getLargest [L] "Get the largest element of a given list L" (cond (empty? L) nil (empty? (rest L)) (first L) :else (let [rest-max (getLargest (rest L))] (if (> (first L) rest-max) (first L) rest-max)))) (defn -main [] (let [L (list 4 5 10 1) largest (getLargest L)] (println "Largest element of" L "is" largest)))
运行后输出结果为:Largest element of (4 5 10 1) is 10
内容的提问来源于stack exchange,提问作者beep
相关产品推荐
相关产品推荐

