2014-06-11 68 views
3

我在我的Clojure得到這個怪異的NPE的Hello WorldClojure的NPE在主

(ns test-app.core 
    (:gen-class)) 

(defn -main [& args] 
    ((println "Hello"))) 

注意額外的()周圍(的println 「你好」)。這似乎是問題,如果我刪除它就好了。

和程序的輸出。注意代碼實際上打印了「Hello」和投擲。

Hello 
Exception in thread "main" java.lang.NullPointerException 
    at test_app.core$_main.doInvoke(core.clj:5) 
    at clojure.lang.RestFn.invoke(RestFn.java:397) 
    at clojure.lang.Var.invoke(Var.java:411) 
    at user$eval5$fn__7.invoke(form-init9064825970813284041.clj:1) 
    at user$eval5.invoke(form-init9064825970813284041.clj:1) 
    at clojure.lang.Compiler.eval(Compiler.java:6619) 
    at clojure.lang.Compiler.eval(Compiler.java:6609) 
    at clojure.lang.Compiler.load(Compiler.java:7064) 
    at clojure.lang.Compiler.loadFile(Compiler.java:7020) 
    at clojure.main$load_script.invoke(main.clj:294) 
    at clojure.main$init_opt.invoke(main.clj:299) 
    at clojure.main$initialize.invoke(main.clj:327) 
    at clojure.main$null_opt.invoke(main.clj:362) 
    at clojure.main$main.doInvoke(main.clj:440) 
    at clojure.lang.RestFn.invoke(RestFn.java:421) 
    at clojure.lang.Var.invoke(Var.java:419) 
    at clojure.lang.AFn.applyToHelper(AFn.java:163) 
    at clojure.lang.Var.applyTo(Var.java:532) 
    at clojure.main.main(main.java:37) 
[Finished in 4.0s with exit code 1] 

我的問題是爲什麼會發生這種情況?

或更好:那麼這是一個錯誤還是預期的行爲?

我認爲這是因爲列表的第一個參數應該是一個函數的名稱,在這裏是另一個列表:P。但是在這種情況下編譯器/運行時不應該給出更好的錯誤?

Thx提前。

回答

5

我認爲這是因爲列表的第一個參數應該是一個函數的名稱,並在這裏它的另一個列表

關閉 - 當代碼進行評估,以列表形式中的第一項是評估,並將結果作爲函數調用(第一項可能是函數的名稱,或者是返回函數的其他函數調用)。在這種情況下,println函數總是返回nil;試圖調用nil作爲函數產生您看到的NPE。

在這種情況下,編譯器/運行時不應該給出更好的錯誤嗎?

不一定 - 編譯器無法提前知道評估內部函數調用的結果是否是用於外部函數調用的有效函數。以下工作蠻好的:

((partial + 1) 2) 

因爲partial返回另一個函數。

+0

有意義:P thx用於快速回復。 – boogie666