resolve 在 REPL 和 -main 中表现不同

resolve behaves different in REPL and -main

我有以下代码

(ns clojure-noob.core
  (:gen-class))

(defn -main [& args]
    (defn A [x] (str x "a"))
    (println (A "."))                        ; .a
    (println A)                              ; some object
    (println (symbol "A"))                   ; just A
    (println (resolve(symbol  "A")))         ; nil
    (println ((resolve(symbol  "A")) "."))   ; nullpointer exception
)

如果我在 repl 中逐行输入行(以 (defn A ... 开头),它们会按预期运行。最后一个

    (println ((resolve(symbol  "A")) "."))

在“.”上调用 A即附加字母 a。 但是在 leiningen 中用 lein run 调用的整个事情在倒数第二行给出了 nil 并且在最后一行给出了一个空指针异常,即 resolve 没有按预期解析。

我做错了什么? lein repllein run 有什么区别?

简短的回答是,当 resolvelein repllein run 中评估时,您的 当前命名空间 是不同的,并且 resolve 适用于 当前命名空间。 resolve 文档字符串:

same as (ns-resolve *ns* symbol) or (ns-resolve *ns* &env symbol)

*ns* 是对当前名称空间的绑定。

你可以通过添加 (println "current ns is" *ns*).

来查看差异

使用 ns-resolve 并显式传递命名空间将使您的代码在这两种情况下都能正常工作:

(println (ns-resolve 'clojure-noob.core (symbol "A")))
(println ((ns-resolve 'clojure-noob.core (symbol "A")) "."))

顺便说一句,您通常看不到 nested defn 即您的 A 函数可以定义为 outside/before -main函数。