Clojure 无resolve变量在def之后返回nil

Clojure 无resolve变量在def之后返回nil,clojure,Clojure,我是Clojure的新手,所以这可能是显而易见的 (println (nil? (resolve 'x))) (def x 1) (println (nil? (resolve 'x))) 这是打印出来的 true true 为什么第二个println不输出false 根据上面的例子,难道不是这样吗 编辑: 我不是通过REPL运行这个 我就是这样到达那里的: 通过lein new testing创建项目 对core.clj进行修改后,如下所示: (ns testing.core (:ge

我是Clojure的新手,所以这可能是显而易见的

(println (nil? (resolve 'x)))
(def x 1)
(println (nil? (resolve 'x)))
这是打印出来的

true
true
为什么第二个
println
不输出
false

根据上面的例子,难道不是这样吗

编辑:

我不是通过REPL运行这个

我就是这样到达那里的:

通过
lein new testing
创建项目

对core.clj进行修改后,如下所示:

(ns testing.core
  (:gen-class))

(defn -main
  [& args]

  (println (nil? (resolve 'x)))
  (def x 1)
  (println (nil? (resolve 'x)))
)
当在运行中运行时,输出为:

true
true

在Clojure REPL中计算这些表达式时,第一个表达式为true,第二个表达式为false。你是如何开始Clojure REPL的?您使用的是什么版本的Clojure?您能否一致地复制此值?

(解析'x)
尝试获取由
x
符号命名(绑定)的变量。如果这个变量不存在,它应该返回nil。所以你的假设是正确的。 如果您使用live REPL进行编码,请记住,您计算的代码将保留在内存中,直到您将其替换为新版本或手动取消定义为止


下面是我这边的可视REPL会话,显示了正确的行为:


您的环境有些奇怪:

~/expr/demo > lein repl
demo.core=> (resolve 'x)
nil
demo.core=> (resolve 'x)
nil
demo.core=> (resolve 'x)
nil
demo.core=> (resolve 'x)
nil
demo.core=> (def x 1)
#'demo.core/x
demo.core=> (resolve 'x)
#'demo.core/x

尝试运行以下程序,并仔细阅读输出。请注意,函数“resolve”的文档字符串表示它解析名称空间中的符号,该符号是*ns*的当前值,是一个“动态变量”,根据下面所示程序的输出,它默认等于“user”名称空间,与定义函数的名称空间不同,这是名称空间,其中“x”是“def”d

(ns testing.core
  (:gen-class))

(defn -main
  [& args]

  (println)
  (println "before (def x 1)")
  (println "*ns*=" *ns*)
  (println "(resolve 'x)=" (resolve 'x))
  (println "(resolve 'user/x)=" (resolve 'user/x))
  (binding [*ns* 'testing.core]
    (println "*ns*=" *ns*)
    (println "(resolve 'x)=" (resolve 'x))
    (println "(resolve 'user/x)=" (resolve 'user/x)))

  (def x 1)
  (println)
  (println "after (def x 1)")
  (println "*ns*=" *ns*)
  (println "(resolve 'x)=" (resolve 'x))
  (println "(resolve 'user/x)=" (resolve 'user/x))
  (binding [*ns* 'testing.core]
    (println "*ns*=" *ns*)
    (println "(resolve 'x)=" (resolve 'x))
    (println "(resolve 'user/x)=" (resolve 'user/x))))
我的系统上的输出:

before (def x 1)
*ns*= #object[clojure.lang.Namespace 0x524f3b3a user]
(resolve 'x)= nil
(resolve 'user/x)= nil
*ns*= testing.core
(resolve 'x)= #'testing.core/x
(resolve 'user/x)= nil

after (def x 1)
*ns*= #object[clojure.lang.Namespace 0x524f3b3a user]
(resolve 'x)= nil
(resolve 'user/x)= nil
*ns*= testing.core
(resolve 'x)= #'testing.core/x
(resolve 'user/x)= nil

我通过在Leiningen内部运行一个项目来实现这一点。您更新的问题使用函数内部的
def
。虽然这样做不是一个错误,而且在一些调试情况下这样做是有用的,但在“生产代码”中,这样做是非常不正常的Clojure代码。你问这个问题是因为你想知道Clojure实现是如何给出这个结果的吗?因为如果你问是因为你想写这样的生产Clojure代码,我的建议是“不要那样做”。我不会通过REPL运行它,即使是使用Leiningen。我用
lein run
运行它(参见我的编辑)。