【问题标题】:Exercism Clojure exercise练习 Clojure 练习
【发布时间】:2026-01-17 00:20:02
【问题描述】:

我正在通过 Exercism 学习 clojure,但在完成千层面问题的最后一部分时遇到了一些麻烦。

指令如下 - 定义带两个参数的总时间函数:第一个参数是您添加到千层面的层数,第二个参数是千层面在烤箱中的分钟数。该函数应返回您烹饪千层面总共花了多少分钟,即准备时间(以分钟为单位)与千层面在烤箱中花费的时间(以分钟为单位)的总和。

这是给我带来麻烦的代码:

(defn prep-time [num-layers]
  (* times-two num-layers))

(def sum (prep-time times-two))

(defn total-time [num-layers actual-time]
  (def test1 (prep-time num-layers))
  (+ test1 actual-time))

(def finished (total-time test1 prep-time))

我收到一条错误消息:

`(defn prep-time [num-layers] 
11:   (* times-two num-layers))    
        ^--sci.impl.fns$fun$arity_1__1213 cannot be cast to java.lang.Number`

为什么我会收到这个错误,这意味着什么?

【问题讨论】:

  • 在顶层使用 def 是不行的(它会修改命名空间) - 它是 test1 内的 total-time 。改为查看let;在另一个 defn 之外再次依赖 (def test1 ...) 也很糟糕。您还可以改进问题并说明您面临的实际问题吗?你得到一个例外或一些断言吗?
  • 堆栈溢出问题应该是关于您遇到的特定技术问题。 “解决这个任务”太宽泛了,不能在这里讨论。诚然,您的代码中存在特定的技术问题,但您的工作是找出其中的一个,构建一个 minimal reproducible example 来重现它,并询问这个问题。
  • 那是我的错,谢谢,下次一定要更清楚地澄清我的问题。但我面临的问题是,当我运行我的代码时,我会收到一条错误消息 - (defn prep-time [num-layers] 11: (* times-two num-layers)) ^--- sci.impl.fns$fun$arity_1__1213 cannot be cast to java.lang.Number 不确定我为什么会收到错误消息。

标签: clojure


【解决方案1】:

要回答您关于转换错误的具体问题,这是因为 times-two 是一个函数,但您将它传递给 *,它期望其参数是数字。

您没有具体说明如何定义 times-two,但我怀疑您的意思是该行是 (times-two num-layers) — 或者只是 (* 2 num-layers)

但是,作为Martin Půda points out,在defn 中使用def 几乎可以肯定是对def 的误用——改用let。你不需要test1 成为一个全局变量——将test1 传递给total-time 是没有意义的,因为total-time 是定义test1 的地方!事实上,通过将test1 传递给total-time,您实际上会将其重新定义为原始值的两倍。

我还建议您重新访问“实际时间”参数的名称选择。我不清楚“实际”时间是什么意思。这不是到目前为止在烤箱中花费的时间吗?也许oven-time 是一个不那么含糊的名字。

【讨论】:

    【解决方案2】:

    不要在defn 中使用def。如果你真的需要一些变量,你可以使用let,但是没有它也可以完成这个练习:

    (ns lucians-luscious-lasagna)
    
    (def expected-time 40)
    
    (defn remaining-time [actual-time]
      (- expected-time actual-time))
    
    (defn prep-time [num-layers]
      (* num-layers 2))
    
    (defn total-time [num-layers actual-time]
      (+ (prep-time num-layers) actual-time))
    

    【讨论】: