【问题标题】:Clojure: namespace and -mainClojure:命名空间和-main
【发布时间】:2012-04-22 10:59:30
【问题描述】:

我正在尝试了解 -main 及其命名空间设置。 -main 函数中的默认命名空间似乎是“用户”,但可以调用在同一文件中的主函数“上方”定义的函数。他们被提及了吗?我正在运行它以找出:

(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)

  • 运行它:

    跑起来

【问题讨论】:

    标签: clojure namespaces scope main leiningen


    【解决方案1】:

    last night in #clojure不是我帮你回答的吗?如果对答案有什么不满意的地方,你必须澄清你的问题。

    【讨论】:

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

    看起来 leiningen 通过从用户命名空间调用它来运行 (-main),如下所示:(ack.doodle/-main)。因此 *ns* 绑定到用户命名空间。

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

    【讨论】:

      猜你喜欢
      • 2011-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-15
      • 2015-09-16
      • 2016-06-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多