在if-else中执行多个语句而不使用nullpointer异常

时间:2011-06-04 01:12:05

标签: clojure

我正在尝试深入研究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")))

如果服务器是nil,一切正常,但如果服务器正在运行,这是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条件创建某种“块”语句。如果我不使用它们,第二个println将被用作其他。

使用let作为某种“阻止” - 陈述:

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

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

1 个答案:

答案 0 :(得分:60)

使用do

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

在Lisps中,通常情况下,您不能只添加用于分组的parens。

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

这里,将尝试调用第一个(println "foo")的返回值(作为函数),并将第二个的返回值作为参数。这些都是非常基本的评估规则,因此我建议您阅读一些关于Clojure或Lisps的介绍性书籍或文档。

来自evaluationClojure homepage部分:

  

非空列表被视为电话   要么是特殊形式,要么是宏,要么是   功能。电话有表格   (操作员操作数*)。

宏或特殊形式可能会“破坏”此规则。