我写了一个递归函数来获得旅程的总费用。 costOfPath只是调用ubergraph来获取每次旅程的成本,然后这个函数添加它们并显示它。
(defn routeCost [parcel cost]
"Calculate the total route cost"
(if (empty? parcel)
(print "Total Journey Cost: " cost)
((def first-parcel (first parcel))
(def start (:start first-parcel))
(def finish (:finish first-parcel))
(def value (costOfPath start finish))
(def parcel-two (rest parcel))
(routeCost parcel-two (+ cost value)))))
(routeCost task8 0)
任务8看起来如此:
(def task8 [(Parcel. :main-office :r131 "Plastic Wallets" "Delivery" 1)
(Parcel. :r131 :r111 "CDs" "Delivery" 1)
(Parcel. :r111 :r121 "USBs" "Collection" 2)
(Parcel. :r121 :main-office "USBs" "Delivery" 2)])
该函数打印出正确的成本,但给出了classCastException。
ClassCastException practice_ubergraph.core.Parcel cannot be cast to clojure.lang.IFn clojure.lang.Var.fn (Var.java:363)
包裹记录:
(defrecord Parcel [start
finish
package
run-type
weight
])
为什么会发生这种情况,如何阻止它?
编辑:我认为它与IF语句以及我将括号放在块周围的方式有关。
答案 0 :(得分:2)
正如Tony所说,尝试将def
s的使用限制在最高水平是个好主意。
您看到ClassCastException
的原因可能就是这一行:
((def first-parcel (first parcel))
您正在定义first-parcel
,然后立即使用外部括号来调用它。
将它与此示例进行比较,该示例生成类似的异常:
((def a 1))
在此示例中,a
获取值1
。 def
返回var #'user/a
,因此评估的表达式为:
(#'user/a)
#'user/a
的值为1
,然后将1
视为函数。
通常,如果您看到cannot be cast to clojure.lang.IFn
寻找一组双括号。
答案 1 :(得分:0)
请不要在函数中使用def。 这是一个更好的一个
(defn route-cost [parcel cost]
"Calculate the total route cost"
(if (empty? parcel)
(print "Total Journey Cost: " cost)
(let [{:keys [start finish]} (first parcel)
value (cost-of-path start finish)]
(route-cost (rest parcel) (+ cost value)))))
clojure的本质是你可以尽可能简洁地编写代码。通常我们在clojure中使用kebab-case来区分Java
使用let功能将修复所有内容