在Clojure中的if语句之后连续运行两个命令

Kev*_*rke 17 clojure

为什么以下Clojure程序会抛出NullPointerException?

user=> (defn x []  
       "Do two things if the expression is true."
       (if true ((println "first expr") (println "second expr")) false))

user=> (x)
first expr
java.lang.NullPointerException (NO_SOURCE_FILE:0)
second expr
Run Code Online (Sandbox Code Playgroud)

这是我实际用例的简化版本,我想在返回映射之前执行三个语句(从DB中提取值) - {:status 200, :body "Hello World"} 在分支内部.

Ran*_*832 34

它试图将第一个println的结果视为调用第二个println函数的函数.

你需要一个do.

(defn x []  
   "Do two things if the expression is true."
   (if true (do (println "first expr") (println "second expr")) false))

(x)
Run Code Online (Sandbox Code Playgroud)

do特殊形式(CL progn这个,开始计划)执行每个参数的序列,并返回最后一个结果.


Dav*_*Ray 11

如果nil在else的情况下作为返回值是正常的,请考虑使用when哪个具有隐式do块:

(defn x []  
  "Do two things if the expression is true."
  (when true
    (println "first expr") 
    (println "second expr")))
Run Code Online (Sandbox Code Playgroud)


bmi*_*are 7

并不是说它在你的特定情况下很重要,但确实知道它们之间的区别是(do ...)将每个表单加载到它自己的类加载器中,还有一个空的let表单(let [] ...),它在单个类加载器中计算整个表单.

  • 在其自己的类加载器中加载每个表单与其他方法之间的实际区别是什么?也许我不明白classloader的含义. (2认同)
  • 例如,您正在编写一个定义自定义deftype和多个类的宏.作为优化,您希望使用相同的类加载器,以便创建更少的类加载器实例. (2认同)