【问题标题】:Clojure float is not being recognizedClojure 浮点数未被识别
【发布时间】:2021-05-21 01:03:58
【问题描述】:

所以我正在使用 Clojure 制作一个简单的程序,计算 BMI 并根据该计算返回该人是否健康。

这是我的代码

(defn bmi [weight height]
(def x (/ weight (Math/pow height 2)))
(println x)

(let [y x]
(cond
  (< y 20.0) "Underweight"
  (< y 25.0 and >= y 20.0) "Normal"
  (< y 30.0 and >= y 25.0) "Obese"
  (< y 40.0 and >= y 30.0) "Obese2"

  :else "Obese3"))
  )

  (bmi 45.0 1.7)

我认为它是正确的,但是当我运行它时它告诉我错误。

CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/and, compile:(/tmp/form-init8921870265637757493.clj:47:3)

谁能帮帮我?谢谢!

【问题讨论】:

标签: java functional-programming clojure


【解决方案1】:

一些小的cmets

  • def 定义“全局”变量,您应该使用let 创建“本地”值。
  • and 是一个宏(此时您几乎可以将其视为一个函数),因此它位于函数位置(而不是其他语言中的运算符)
  • &lt; 等函数可以接受超过 2 个参数,如果订单被保留,它们会返回 true(例如,(&lt; 1 2 3) 返回 true

使用上述方法,您可以更新您的 bmi 函数,如下所示:

(defn bmi [weight height]
  (let [x (/ weight (Math/pow height 2))]
    (println x)
    (let [y x] ;; You could have used 'x' in the code below too
      (cond
        (< y 20.0) "Underweight"
        (< 20.0 y 25.0) "Normal"
        (< 25.0 y 30.0) "Obese"
        (< 30.0 y 40.0) "Obese2"
        :else "Obese3"))))

;; (bmi 45.0 1.7) ;; => "Underweight"

;; Show `and` over `<` versus plain `<`:
;; (and (< 1 2) (< 2 3)) ;; => true
;; (< 1 2 3) ;; => true

【讨论】:

  • 像这样链接&lt;会产生令人不快的断点。如果y 为20,则不匹配大小写,结果为“Obese3”。相反,只需完全删除每个子句的前半部分。它上面的子句都失败了,所以我们在第二个子句中已经知道y至少是20。
  • 很好,我在从cond 中的每个测试中删除ands 时错过了它。
【解决方案2】:

cond 在子句为true 时停止,因此如果您在第一个子句中查找 &lt; 20 在下一个你不必寻找&gt;= 20。 此外,您在此处使用的 sintax 不正确: (&lt; y 25.0 and &gt;= y 20.0) "。这应该是(and (&lt; y 25.0) (&gt;= y 20.0)),但您不需要第二部分,因为您在 ((let [x y]),您可以继续使用x,因为它们具有相同的值。 所以,你的函数应该是这样的:

(defn bmi [weight height]
  (let [x (/ weight (Math/pow height 2))]
    (println x)
    (cond
      (< x 20.0) "Underweight"
      (< x 25.0) "Normal"
      (< x 30.0) "Obese"
      (< x 40.0) "Obese2"
      :else "Obese3")))

【讨论】:

    【解决方案3】:

    您错误地使用了and。你写了例如

    (< y 25.0 and >= y 20.0)
    

    应该写

    (and (< y 25.0) (>= y 20.0))
    

    另外,在函数中使用def 来创建全局不是一个好习惯。我建议

    (defn bmi [weight-kg height-m]
      (/ weight-kg (* height-m height-m)))
    
    (defn bmi-descrip [weight-kg height-m]
      (let [bmi-val  (bmi weight-kg height-m)]
        (println bmi-val)
    
        (cond
          (< bmi-val 20.0)                         "Underweight"
          (and (< bmi-val 25.0) (>= bmi-val 20.0)) "Normal"
          (and (< bmi-val 30.0) (>= bmi-val 25.0)) "Obese"
          (and (< bmi-val 40.0) (>= bmi-val 30.0)) "Obese2"
          :else                                    "Obese3")))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-28
      • 2013-04-10
      • 2016-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多