Clojure - 为什么分组需要"do"语句?

Ste*_* B. 2 clojure

我知道do块将按顺序执行语句并返回最后一个语句的值.我会,如果我不需要返回值的做的是不必要的.不考虑返回值,那么,我不明白这两个函数的不同行为:

与"做":

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

=> (x) 
a
b
nil
Run Code Online (Sandbox Code Playgroud)

没有"做":

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

=> (x) 
a
b
NullPointerException   user/x (NO_SOURCE_FILE:3)
Run Code Online (Sandbox Code Playgroud)

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

Cha*_*ffy 6

因为

(function argument)
Run Code Online (Sandbox Code Playgroud)

...是函数调用语法,

((println "a") (println "b"))
Run Code Online (Sandbox Code Playgroud)

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

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


顺便说一句,这里惯用​​的事情就是if用a 代替你when,这将扩展到隐含地包括do:

(defn x [] 
  (when true 
     (println "a")
     (println "b")))
Run Code Online (Sandbox Code Playgroud)