评论由:alexmiller 提出
编译器正在尝试确定函数位置中的“东西”是否是宏 var 需要在 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 找到一个映射到不是 var 的符号,抛出我们看到的 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)