Clojure: 命名空间和-main

4
我正在尝试理解-main及其命名空间设置。在-main函数中,默认命名空间似乎是“user”,但是在同一文件中“上方”定义的函数可以被调用。它们是否有所关联?我运行了以下代码来查找答案:
(ns ack.doodle)

(defn fo [] "bar")

(defn -main [& args]
  (println (fo))                               ;; bar
  (println *ns*)                               ;; #<Namespace user>
  (println (get (ns-refers *ns*) 'sorted-map)) ;; #'clojure.core/sorted-map
  (println (get (ns-refers *ns*) 'fo))         ;; nil
  (println (get (ns-map *ns*) 'fo))            ;; nil
  (println (get (ns-publics *ns*) 'fo))        ;; nil
  (println (get (ns-interns *ns*) 'fo))        ;; nil
  (println (get (ns-aliases *ns*) 'fo))        ;; nil
  (println (ns-resolve *ns* 'fo)))             ;; nil

呼叫 (fo) 成功了,但显然符号“fo”在当前命名空间 *ns* 中未知。是怎么回事呢?
当我试图将某个函数的名称以及一些参数作为命令行参数传递给 -main 时,遇到了这个问题。
重现步骤:
- 将上述代码粘贴到文件./src/ack/doodle.clj中 - 创建./project.clj文件并添加以下内容: (defproject ack "1" :main ack.doodle) - 运行它: lein run
2个回答

0

看起来 leiningen 是通过从用户命名空间调用 (-main) 来运行的,就像这样:(ack.doodle/-main)。因此 *ns* 绑定到用户命名空间。

尝试在您的项目根目录中运行 lein repl。然后运行 (-main),看看会发生什么。 :)


-1

我不是昨晚在 #clojure 已经回答了你这个问题 ?如果我的回答有什么不满意的地方,你需要澄清你的问题。


很抱歉昨天我没能看到你的回答,我想在我有机会阅读它之前就断开了连接。大约一个小时后,我重新加入了频道并询问是否有人回答了我的问题,但没有得到回应。我不知道在编译时和运行时可能有不同的命名空间绑定。无论如何,对我来说仍然不是完全清楚的是为什么(fo)调用在运行时成功,即使显然'fo在当前命名空间中在运行时未知。所以也许问题应该是:如何确定对*ns*中函数的调用是否成功? - Lars Bohl
还有,我不知道频道日志。糟糕 :D - Lars Bohl
*ns* 的运行时值与函数调用成功无关。在编译时,编译器看到你正在调用 foo,在 *ns* 中查找它(这个时候 绑定),并发出对 ack.doodle/foo 的引用。在运行时,该引用已经解析,因此 *ns* 的值没有影响(这就是为什么它不再绑定的原因)。不过我不理解你澄清后的问题 -“如何确定对 *ns* 中函数的调用是否会成功”对我来说没有意义。 - amalloy
谢谢您的解释,我觉得我开始更好地理解这个问题了(是的,现在看来,我的澄清后的问题似乎有点无意义)。 - Lars Bohl
页面未找到!知识丢失! - jgomo3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接