Clojure 无resolve变量在def之后返回nil
我是Clojure的新手,所以这可能是显而易见的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
(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
运行它(参见我的编辑)。