7

在检查符号是否可以解析时,我会遇到一些奇怪的行为。

user=> ok
CompilerException java.lang.RuntimeException: Unable to resolve symbol: ok in this context, compiling:(NO_SOURCE_PATH:0)
user=> (resolve 'ok)
nil
user=> (if (resolve 'ok) "bla" (def ok 'ok))
"bla"
user=> ok
#<Unbound Unbound: #'user/ok>
user=> (def ok 'ok)
#'user/ok
user=> ok
ok

谁能告诉我这可能来自哪里?这种行为是有意的吗?

4

2 回答 2

4

(def ok "whatever")创建一个ok 在编译时命名的变量。编译器扫描整个表单以编译它,发现您将定义一个名为 的 var ok,并在您的表单实际执行之前为您创建它(没有绑定)。当def表单实际执行时,表达式的运行时值将分配给 var user/ok。在您的示例中,这永远不会发生,因为 var 已经创建,而if分支则相反。

使用bound?作为替代是一个糟糕的想法,因为它测试了一些完全不同的东西:命名的 var(必须存在)是否具有永久绑定或线程本地绑定。

于 2012-01-15T07:02:06.693 回答
1

由于我只在宏中使用它,我现在按如下方式使用它

(defmacro bla [x]
    (if (resolve x) x `(def ~x '~x)))

现在它可以工作了,因为 def 在引用的表单内并在解析后评估。

于 2012-01-16T08:53:42.103 回答