clojure代码给出错误:java.lang.Integer无法强制转换为clojure.lang.IFn

时间:2014-01-08 19:55:44

标签: clojure classcastexception

嗨,我有这个学校项目,我差不多完成了所以我不需要代码的帮助,问题是我从来没有在clojure中编码但是为了这个任务必须尝试并在clojure中捕获宏绑定表单,有一些REPL命令可以为赋值传递提供不同的响应,

无论如何我得到一个错误,我一直在谷歌搜索,但没有任何具体的这个问题,大多数解释基本上需要有自己的解释似乎没有初学者适应所以它对我没有多大帮助。

(defmacro safe [bindings & code]
(if (list? bindings)
`(try 
   ~bindings 
  (catch Throwable except# except#)) 

(if (= (count bindings) 0)
  `(try ~code 
     (catch Throwable except# except#)) 

  `(let ~(subvec bindings 0 2)

     (try
       (safe ~(subvec bindings 2) ~@code)
       (catch Throwable except# except#) 

       (finally
         (. ~(bindings 0) close))))))) ;;safe



(def divider(safe (/ 1 0)))
(def reader (safe [s (FileReader. (java.io.File. "C:/text.txt"))] (. s read)))

所以我得到的错误是

=> (def v (safe [s (FileReader. (java.io.File. "C:/text.txt"))] (. s read)))
#'myProject.core/v
=> v
#<ClassCastException java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn>

所有知道clojure的人请告诉我一些关于错误的提示,我得到的所有提示是应该有一个错位的错误,我已经反复检查了代码但是找不到任何错误类型等等。谢谢你!

3 个答案:

答案 0 :(得分:5)

使用macroexpand和朋友帮助调试

(def form (quote (safe [s (FileReader. (java.io.File. "test.txt"))] (. s read))))

(pprint (macroexpand form)) ;=>
(let*
 [s (FileReader. (java.io.File. "test.txt"))]
 (try
  (user/safe [] (. s read))  ; <--- Macro is recursive
  (catch java.lang.Throwable except__1104__auto__ except__1104__auto__)
  (finally (. s user/close))))

宏是递归的,所以这不是完全扩展

(pprint (clojure.walk/macroexpand-all form)) ;=>
(let*
 [s (new FileReader (new java.io.File "test.txt"))]
 (try
  (try
   ((. s read)) ; <-- Too many parenthesis! 
   (catch ...

read调用返回一个整数,该整数又被称为递归宏扩展中的函数。

答案 1 :(得分:0)

 (FileReader. (java.io.File. "/tmp/text.txt"))

为您提供文件中第一个字符的值

  

cat /tmp/text.txt =&gt; ABCD

     

(let [s(FileReader。(java.io.File。“/ tmp / text.txt”))](。s read))=&gt; 97

相同
  

(int \ a)

你的宏期待一个功能。尝试:

(safe [s (FileReader. (java.io.File. "/tmp/text.txt"))] #(+ 6))(safe [s (FileReader. (java.io.File. "/tmp/text.txt"))] (fn [] (. s read)

答案 2 :(得分:0)

<强>解决!

在第三个try块中缺少非引号切片,导致异常

java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

这是由于在递归阅读时引起的额外禁忌造成的,

macroexpand ex。

(pprint (macroexpand-all form)) 
 (let*[s
  (new FileReader 
   (new File "test.txt"))]
    (try
     (try
       ((.s read)) ;<= here

必须从

更改第三次尝试/捕获
(try
   (safe ~(subvec bindings 2) ~@code)

为:

(try
   (safe ~@(subvec bindings 2) ~@code)

根据我的理解,问题是我返回了一个列表,其中包含一个像(1(2 3))这样的paranthesis在读取时导致异常,unquoting使它看起来(1 2 3)并且可以读取或(在这种情况下)从java转为clojure。

预订misspellz或者叫错了名字! :)

非常感谢A.Webb和patz。