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

clojure代码给出错误:无法将java.lang.Integer转换为clojure.lang.IFn,clojure,classcastexception,Clojure,Classcastexception,嗨,我有一个学校的项目,我几乎完成了,所以我不需要代码方面的帮助,问题是我从来没有在clojure中编写过代码,但是对于这个作业,我必须在clojure中使用绑定表单执行try-and-catch宏,有一些REPL命令预期会给出不同的响应,以便作业通过 无论如何,我得到了一个错误,我一直在谷歌搜索,但没有什么是具体的这个问题,大多数解释基本上需要有自己的解释,没有什么似乎是初学者适应,所以它没有做太多的我 (defmacro safe [bindings & code] (if (lis

嗨,我有一个学校的项目,我几乎完成了,所以我不需要代码方面的帮助,问题是我从来没有在clojure中编写过代码,但是对于这个作业,我必须在clojure中使用绑定表单执行try-and-catch宏,有一些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>
=>(def v(安全[s(FileReader.(java.io.File.C:/text.txt”))](.s read)))
#'myProject.core/v
=>v
#

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

使用
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))))
(def表单(引号(safe[s(FileReader.(java.io.File.test.txt)))](.s read)))
(pprint(宏展开形式));=>
(让*
[s(FileReader.(java.io.File.“test.txt”)]
(试试看
(用户/安全[](.s读取));
(让*
[s(新的文件阅读器(新的java.io.File“test.txt”)]
(试试看
(试试看

(.s read));使用
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))))
(def表单(引号(safe[s(FileReader.(java.io.File.test.txt)))](.s read)))
(pprint(宏展开形式));=>
(让*
[s(FileReader.(java.io.File.“test.txt”)]
(试试看
(用户/安全[](.s读取));
(让*
[s(新的文件阅读器(新的java.io.File“test.txt”)]
(试试看
(试试看
(s read);;
正在为您提供文件中第一个字符的值

cat/tmp/text.txt=>abcd

(让[s(FileReader.(java.io.File./tmp/text.txt”)](.s read))=>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)

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

cat/tmp/text.txt=>abcd

(让[s(FileReader.(java.io.File./tmp/text.txt”)](.s read))=>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)
已解决!

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

java.lang.ClassCastException:java.lang.Integer不能强制转换为clojure.lang.IFn

这是因为反复阅读s时产生了额外的偏执

宏扩展

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

据我所知,问题是我得到了一个类似于(1(23))的偏执列表,在读取时会导致异常,取消引用使其看起来(1 2 3),并且可以从java读取或(在本例中)转换为clojure

拼写错误或叫错名字的预订!:)


非常感谢A.Webb和patz。

解决了!

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

java.lang.ClassCastException:java.lang.Integer不能强制转换为clojure.lang.IFn

这是因为反复阅读s时产生了额外的偏执

宏扩展

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

据我所知,问题是我得到了一个类似于(1(23))的偏执列表,在读取时会导致异常,取消引用使其看起来(1 2 3),并且可以从java读取或(在本例中)转换为clojure

拼写错误或叫错名字的预订!:)


非常感谢A.Webb和patz。

您好,谢谢您的帮助,但是aasignment特别指出,如果我要更改上面提到的命令,它可能会被视为我正在使用Shortcuts,我必须说这确实有效,但仍然不确定我是否可以这样使用它。您好,谢谢您的帮助,但是aasignment特别指出,如果我要更改上面提到的命令,它可能会被视为我正在使用Shortcut!我必须说这实际上正在工作!但仍然不确定我是否允许以这种方式使用它。我现在不在计算机上,但这看起来很好!所以macroexpand是调试器?并且您编写的代码是用REPL编写的,对吗?它在调试中很有用,但不是调试器。它按照说明执行-在评估宏之前显示宏的扩展。您可能会发现,使用
defn
而不是
defmacro
创建宏的函数版本,
safe fn
,这很有指导意义,然后请注意ling
safe fn
及其所有参数都单独引用,其输出与在引用的宏调用上执行
macroexpand-1
相同。是的,这是来自REPL会话。所以让我澄清一下,我的错误是由额外的妄想引起的吗?所以我所要做的就是找到它并摆脱它,错误就会消失?伙计“我整个上午都在不遗余力地尝试获得与您相同的结果,我不确定如何使用您评论中的friend部分,但继续测试macroexpand。请告诉我我是否做得对:这是保存表单以便可以对其进行复制,对吗?
user=>(def form)(quote)(safe[s(FileReader)。(java.io.File)。“test.txt”)](.s read)))
这里我们正在扩展表单,以便在评估之前调试/跟踪正在发生的事情,对吗?
user=>(clojure.print/pprint(macroexpand表单))
下一步应该打印扩展?我遗漏了某些部分?您可以从
宏扩展的一个级别看到没有可见的额外括号。使用
(try
   (safe ~(subvec bindings 2) ~@code)
(try
   (safe ~@(subvec bindings 2) ~@code)