具有多个if语句的clojure

具有多个if语句的clojure,clojure,Clojure,当我调用math()函数时,到“times”,REPL返回nil。当我使用“添加”时,效果很好。。。救命啊 (defn math [opr x y ] (if(= opr "times") (* x y) ) (if(= opr "add") (+ x y) ) ) (math "times" 8 8) 在Clojure中,最后一条语句是Return语句。所以Clojure检查“times”,即使它是真的,它也会检查“add”,因

当我调用math()函数时,到“times”,REPL返回nil。当我使用“添加”时,效果很好。。。救命啊

(defn math [opr x y ]
    (if(= opr "times")
        (* x y)
    )
    (if(= opr "add")
        (+ x y)
    )
)
(math "times" 8 8)

在Clojure中,最后一条语句是Return语句。所以Clojure检查“times”,即使它是真的,它也会检查“add”,因为您的调用是用“times”进行的,所以第二个if的计算结果为nil。这是返回的

您可以使用
do
或嵌套if语句来解决问题。

我喜欢对多个条件使用语句

;; Will return nil if the cond statement fails all the predicates
(defn math [opr x y ]
  (cond (= opr "times") (* x y)
        (= opr "add") (+ x y)))
WeGi是正确的,因为Clojure将始终返回函数中的最后一条语句。

在所有谓词都具有相同结构时工作:

(defn my-calc
  [operator x y]
    (condp = operator
      "times" (* x y)
      "plus" (+ x y))) 

=> (var user/my-calc)
(my-calc "times" 2 3)
=> 6
(my-calc "plus" 2 3)
=> 5

问题是您的函数是由两个子句组成的序列
if
-forms

  • Clojure依次执行序列的元素,返回 上次会议的结果
  • 如果条件失败,则双子句
    If
    -表单返回
    nil
最快的修复是嵌套
if
s:

(defn math [opr x y]
  (if (= opr "times")
    (* x y)
    (if (= opr "add")
      (+ x y))))
但是,有更好的方法:

(defn math [opr x y]
  (case opr
    "add" (+ x y)
    "times" (* x y)))
。。。而且,抛开C/Java习惯用法

(defn math [opr x y]
  ((case opr
     "add" +
     "times" *)
   x y))
。。。或者

(defn math [opr x y]
  (({"add" +, "times" *} opr) x y))

记住,函数的最后一个表达式是返回的表达式。在代码中,如果
opr
不等于
“add”
,则返回值始终为
nil
。您可能想考虑使用case语句。次要注释:(如果x y)是Culjure中的表达式,而不是语句。我想我应该提到它以避免进一步的混淆:干杯那些被孤立的括号是什么?
do
本身并不能解决这个问题,因为
do
仍然返回它的尾部值。使用
do
会产生副作用,而且会令人讨厌
cond
if
嵌套是这里唯一真正正确的答案。