我写了一个宏:
(defmacro te [a b & c] `(print ~(a b c)))
并运行
(te print 2 inc 4)
得到了一个错误 ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn user/eval8010 (form-init8519408738377285198.clj:1)
然后我跑
(macroexpand-1 '(te print 2 3 4) ;=> (clojure.core/print (3 4))
这意味着(print 2 (3 4))
回归(3 4)
?功能print
有bug吗?
我的clojure版本1.7.0,JVM版本1.8.0_65-b17
更新
好的,举例不容易理解这个例子.
即使我跑了
(te print 2 inc 4) user=> (te print 2 inc 4) ;=> 5nil user=> (macroexpand-1 '(te print 2 inc 4)) ;=> (clojure.core/print (inc 4))
它会打印5
并返回nil
,这意味着(print 2 (inc 4))
返回形式(inc 4)
?
这完全没有关系print
.
这意味着
(print 2 (3 4))
回归(3 4)
?
这不是它的意思,这就是问题的根源.它的意思是" print
用第一个参数调用函数,用2
第二个参数调用值(3 4)
".表达式(3 4)
没有有效值,因为它意味着" 3
带参数的调用函数4
",这就是你得到异常的原因:3是一个Long(数字)并且不能作为函数调用(在clojure内部,它没有实现IFn函数接口).
作为旁注,如果我理解你想要实现的目标(我可能是错的)你的宏可以很容易地写成一个函数,这通常意味着你应该把它写成一个函数,因为函数更容易处理并与其他功能更好地合作.