2011-10-08 47 views
3

我們有一個簡單的函數定義:誤差定義功能時,如果

(defn calculate [d x y] 
    ((if (and (== d 1) (== x 1) (== y 0)) 
    1 
    0))) 
(println (calculate 1 1 0)) 

但導致這個錯誤:

Exception in thread "main" java.lang.reflect.InvocationTargetException 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:616) 
    at jline.ConsoleRunner.main(ConsoleRunner.java:69) 
Caused by: java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn 
    at user$calculate.invoke(main.clj:13) 
    at user$eval5.invoke(main.clj:17) 
    at clojure.lang.Compiler.eval(Compiler.java:6465) 
    at clojure.lang.Compiler.load(Compiler.java:6902) 
    at clojure.lang.Compiler.loadFile(Compiler.java:6863) 
    at clojure.main$load_script.invoke(main.clj:282) 
    at clojure.main$script_opt.invoke(main.clj:342) 
    at clojure.main$main.doInvoke(main.clj:426) 
    at clojure.lang.RestFn.invoke(RestFn.java:408) 
    at clojure.lang.Var.invoke(Var.java:401) 
    at clojure.lang.AFn.applyToHelper(AFn.java:161) 
    at clojure.lang.Var.applyTo(Var.java:518) 
    at clojure.main.main(main.java:37) 
    ... 5 more 

(順便說一句,13號線與ifand行)。

同樣與向量:

(defn calculate [vectorr] 
    ((if (and (== (vectorr 0) 1) (== (vectorr 1) 1) (== (vectorr 2) 0)) 
    1 
    0))) 
(println (calculate [1 1 0])) 

這導致:

Caused by: java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn 

...相同。

並配有地圖:

(defn calculate [mapp] 
    ((if (and (== (mapp :d) 1) (== (mapp :x) 1) (== (mapp :y) 0)) 
    1 
    0))) 
(println (calculate {:d 1 :x 1 :y 0})) 

結果在同一消息:

Caused by: java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn 

我們認爲是有事情做與if,或比較。我們用普通的參數,一個向量作爲參數和一個地圖來嘗試它,顯然,錯誤保持不變。

我們還嘗試了許多其他變體,而沒有更深入地瞭解實際問題。

+2

一般來說,如果您看到多個左側相鄰的人,您可能做錯了什麼。 –

+0

@Alex - 非常棒的小費!在你真正想要這樣的情況下(即應用一個返回的高階函數),那麼它仍然有用做一個雙重拍攝...... – mikera

+0

請注意'if'和'和'**不是**函數。 –

回答

6

你的函數體附近有一對額外的括號,這意味着你想調用if(它可以是1或0--即一個長)的結果。

它應該是:

(defn calculate [vectorr] 
    (if (and (== (vectorr 0) 1) (== (vectorr 1) 1) (== (vectorr 2) 0)) 
    1 
    0)) 
+0

嗯,我明白了。愚蠢的括號,愛他們! - 這可以解決問題。謝謝你快速的回覆! – enlightened

-1

額外的括號導致程序崩潰具有因他們改變你的表達式的返回類型。通過在括號中包含某些東西,在clojure中,您將包含一個表達式作爲函數。然後,引用該函數輸出的程序現在實際上引用了函數本身。

我發現,90%的時間,如果我在clojure中得到類轉換異常,那是因爲我在事故中創建了一個cloSure。

+4

「通過在括號中包含某些東西,在clojure中,您將包含一個表達式作爲函數。」這並不完全正確。通過將括號內的東西包含在內,可以將其稱爲函數 - 不會將其包含在任何內容中,而且您也不會創建閉包。 – sepp2k

+0

也謝謝!也可能只是因爲我們在屏幕前花費太多時間而變得愚蠢...... – enlightened