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 コンパイル時にという名前の変数を作成します。コンパイラはフォーム全体をスキャンしてコンパイルし、okフォームが実際に実行される前に、という名前のvarを定義していることを検出し、(バインディングなしで)作成します。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 に答える