评论由:alexmiller 发表
编译器正在尝试确定函数位置的元素是否为变量宏,该变量宏在Compiler.isMacro()中需要展开。
在(java.net.URI "http://google.com")的情况下,lookupVar确定java.net.URI是一个未映射的符号,因此不进行展开(这当然会在评估时失败,抛出"ClassCastException: java.lang.Class cannot be cast to clojure.lang.IFn"。
在(URI "http://google.com")的情况下,lookupVar找到一个符号,该符号映射到不是变量的东西,并抛出观察到的RuntimeException。
我预期在使用宏展开过程中,这两个都不会抛出错误(基本上和它们开始时一样),并且当它们被评估时,应该抛出相同的错误。附上一个补丁,该补丁只在 internNew 的情况下抛出错误(在这种情况下,你意外地发现除了 var 以外的东西,你应该仍然报告错误,否则只返回 null - lookupVar 没有找到 var)。
internNew 的情况会产生
(import java.net.URI) (def URI "abc") ;; java.lang.RuntimeException: 预期 var,但 URI 映射到类 java.net.URI
使用补丁后的结果
user=> (macroexpand '(java.net.URI "http://google.com")) (java.net.URI "http://google.com") user=> (macroexpand '(URI "http://google.com")) (URI "http://google.com") user=> (java.net.URI "http://google.com") ClassCastException 类 java.lang.Class 不能转换为 clojure.lang.IFn user/eval9 (NO_SOURCE_FILE:6) user=> (URI "http://google.com") ClassCastException 类 java.lang.Class 不能转换为 clojure.lang.IFn user/eval11 (NO_SOURCE_FILE:7)