在使用:gen-class
进行提前编译时,是否可以在多个源文件上拆分Clojure命名空间? (:main true)
和(defn- ...)
如何发挥作用?
答案 0 :(得分:133)
当然,事实上,clojure.core
名称空间本身可以通过这种方式进行分割,并提供了一个很好的模型,您可以通过查看src/clj/clojure
来查看:
core.clj
core_deftype.clj
core_print.clj
core_proxy.clj
..etc..
所有这些文件都参与构建单个clojure.core
命名空间。
其中一个是主文件,其名称与命名空间名称相匹配,以便在有人在:use
或:require
中提及时找到它。在这种情况下,主文件为clojure/core.clj
,并以ns
形式开头。这是您应该将所有命名空间配置放在哪里,而不管您的其他文件可能需要它们。这通常包括:gen-class
,所以类似于:
(ns my.lib.of.excellence
(:use [clojure.java.io :as io :only [reader]])
(:gen-class :main true))
然后在主文件中的适当位置(最常见的是在最后)使用load
来引入帮助文件。在clojure.core
中,它看起来像这样:
(load "core_proxy")
(load "core_print")
(load "genclass")
(load "core_deftype")
(load "core/protocols")
(load "gvec")
请注意,您不需要当前目录作为前缀,也不需要.clj
后缀。
每个帮助文件应首先声明它们正在帮助哪个命名空间,但应使用in-ns
函数执行此操作。因此,对于上面的示例命名空间,帮助程序文件都将以:
(in-ns 'my.lib.of.excellence)
这就是全部。
因为所有这些文件都构建了一个命名空间,所以您定义的每个函数都可以位于任何主文件或帮助文件中。这当然意味着您可以在任何您喜欢的文件中定义gen-class
函数:
(defn -main [& args]
...)
请注意,Clojure的正常定义顺序规则仍然适用于所有函数,因此您需要确保在尝试使用>之前加载了定义函数的任何文件 em>那个功能。
您还询问了定义命名空间私有函数的(defn- foo ...)
表单。这样定义的函数以及其他:private
变量在定义它们的命名空间内是可见的,因此主数据库和所有帮助程序文件都可以访问到目前为止加载的任何文件中定义的私有变量。 / p>