我知道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的原因是什么?
因为
(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)