【问题标题】:Why am i getting a ClassCastException in this recursive function [duplicate]为什么我在这个递归函数中得到一个 ClassCastException [重复]
【发布时间】:2017-03-21 12:57:08
【问题描述】:

我编写了一个递归函数来获取旅程的总成本。 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 语句以及我在块周围放置方括号的方式有关。

【问题讨论】:

    标签: recursion clojure


    【解决方案1】:

    正如 Tony 所说,尝试将 defs 的使用限制在顶层是个好主意。

    您看到ClassCastException 的原因可能是这一行:

    ((def first-parcel (first parcel))
    

    您正在定义first-parcel,然后立即使用括号外集调用它。

    将其与生成类似异常的示例进行比较:

    ((def a 1))
    

    在此示例中,a 获取值 1def 返回 var #'user/a,因此计算的表达式为:

    (#'user/a)
    

    #'user/a 的值为1,然后将1 视为一个函数。

    一般来说,如果您看到cannot be cast to clojure.lang.IFn,请寻找一组双括号。

    【讨论】:

      【解决方案2】:

      请不要在函数中使用 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 可以解决所有问题

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-08-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多