1

仕様によるとdef、現在の ns (つまり *ns*) で var をインターンする必要があります。ただし、次のコードは似ていません。

(ns namespace-b)

(defn def_something []
  (ns namespace-a)
  (println *ns*) ;prints namespace-a as it should
  (def something 1)
) 

(def_something)

(println namespace-b/something) ; prints 1 
(println namespace-a/something) ; throws

私は何が欠けていますか?

ノート:

  • defn明確にするためにのみ使用されます。匿名関数の定義と実行も同様に機能します。
  • def内部関数を使用することは、おそらくあまり慣用的ではないことを私は知っています。ただし、これは私が遭遇したより大きな問題の本質を抽出したものです。
4

2 に答える 2

3

パーサーは、コンパイル時に既に var を現在の名前空間にインターンしていますが、すぐにはバインドされません。

(defn dd [] (def x 0))
x ;; => #<Unbound Unbound: #'user/x>

関連するコードはここにあります。2 番目のパラメーターは、lookupVar存在しない変数に対して前述のインターンをトリガーします

次に、解析によって、以前に作成された var を参照する式が生成されるため、式のロジックが現在の名前空間を離れることはありません。

TL;DR: defコンパイラが特別な方法で処理するものです。

于 2014-10-27T14:05:35.323 に答える