Clojure defmacro cannot be cast to clojure.lang.IFn
defmacro 和 defn有着微妙的区别, 不注意的话会出现难以理解的错误. 下面的的macro只是简单的将参数中的每个元素转换成字符串.
(defmacro foo [form] (map #(str %) form) ) (foo [ALL hello world 3 abc whatever])
抛出错误
ClassCastException java.lang.String cannot be cast to clojure.lang.IFn user/eval11560 (init.clj:9)
原因是我将defmacro当成defn一样了, 对于defmacro, 任何其返回的东西会被当成Clojure代码, 并交给eval函数运行, 这里map的返回值是一个字符串列表
=>(macroexpand '(foo [ALL hello world 3 abc whatever])) ("ALL" "hello" "world" "3" "abc" "whatever")
那么列表的第一个元素"ALL"会被当成函数名, 然而他并不是函数, 因此会报错.
如果要查看转换后的内容, 像上面用macroexpand或者打印
(defmacro foo [form] (pprint(map #(str %) form)) )