在if-else中执行多个语句,没有nullpointerexception

我试图深入探讨clojure和函数式编程。

在我的代码的某些时候,我有一个(def server (spawn-server)) 。 现在我想要一个简短的REPL函数来检查这个套接字的状态。

这是我现在所拥有的:

 (defn status [] (if server ( (println "server is up and running") (println "connections:" (connection-count server)) ) (println "server is down"))) 

如果服务器是零,一切工作正常,但这是REPL的输出,如果服务器正在运行:

 => (status) server is up and running connections: 0 #<CompilerException java.lang.NullPointerException (NO_SOURCE_FILE:0)> 

我不确定是否看到这个问题,但我不知道这应该如何工作:-)我在这里是这样的:

 ((println "foo")(println "foo")) 

这将被评估为(nil nil) ,这将导致NullPointerException?

通常我不会使用外部圆括号,但是如何为if条件创build某种“块”语句。 如果我不使用它们,第二个println将被用作其他的。

有什么可行的是let作为某种“块” – 陈述的用法:

 (let [] (println "server is up and running"), (println "connections:" (connection-count server)) ) 

但是我不确定这是否是“正确”的解决scheme?

使用do

 (defn status [] (if server (do (println "server is up and running") (println "connections:" (connection-count server))) (println "server is down"))) 

在Lisp中,一般来说,不能只添加用于分组的元素。

 ((println "foo") (println "foo")) 

在这里,第一个(println "foo")的返回值将被尝试调用(作为函数),第二个返回值作为参数。 这些都是非常基本的评估规则,所以我build议你打一些有关Clojure或Lisp的介绍性书籍或文档。

从Clojure主页的评估部分:

非空列表被视为对特殊窗体,macros或函数的调用。 一个调用的forms(操作符操作数*)。

macros或特殊forms可能会“打破”这个规则。