Clojure - 为什么"做"分组所需的声明?

时间:2015-04-13 17:28:17

标签: clojure

我知道 do 块会按顺序执行语句并返回最后一个语句的值。我想 如果我不需要返回值,那就不需要了。不考虑返回值,那么,我不理解这两个函数的不同行为:

用"做":

(defn x [] 
  (if true 
     (do (println "a") (println "b"))))

=> (x) 
a
b
nil

没有"做":

(defn x [] 
  (if true 
     ((println "a") (println "b"))))

=> (x) 
a
b
NullPointerException   user/x (NO_SOURCE_FILE:3)

第二个例子中NullPointer的原因是什么?

1 个答案:

答案 0 :(得分:6)

由于

(function argument)

...是函数调用语法,

((println "a") (println "b"))

...希望(println "a")返回一个函数,它可以调用(println "b")作为第一个参数传递的结果。

相反,(println "a")没有返回值(返回nil,aka null),并尝试将此null值作为函数调用,为您提供NullPointerException。


顺便说一句,这里惯用​​的事情是将if替换为when,这将扩展为隐式包含do

(defn x [] 
  (when true 
     (println "a")
     (println "b")))