将Clojure命名空间拆分为多个文件
当使用:gen-class
进行提前编译时,是否可以将Clojure命名空间分割为多个源文件? (:main true)
和(defn- ...)
如何发挥作用?
概观
当然你可以,实际上clojure.core
命名空间本身就是这样分裂的,并提供了一个很好的模型,你可以通过在src/clj/clojure
查看:
core.clj core_deftype.clj core_print.clj core_proxy.clj ..etc..
所有这些文件参与构build单个clojure.core
命名空间。
主文件
其中一个是主文件,命名为与命名空间名称相匹配,以便在某人:use
或:use
:require
时find它。 在这种情况下,主文件是clojure/core.clj
,它以ns
forms开始。 这是你应该把你所有的命名空间configuration,无论你的其他文件可能需要它们。 这通常包括: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)
这一切都需要。
创一stream
由于所有这些文件都在构build一个名称空间,因此您定义的每个函数都可以位于任何主文件或帮助程序文件中。 这当然意味着你可以在你想要的任何文件中定义你的gen-class
函数:
(defn -main [& args] ...)
请注意,Clojure的正常的定义顺序规则仍然适用于所有函数,所以在尝试使用该函数之前,需要确保无论文件定义了哪个函数。
私人的瓦尔
您还询问了定义名称空间专用函数的(defn- foo ...)
表单。 像这样定义的函数以及其他的:private
variables在它们被定义的名称空间内是可见的,所以主和所有的帮助文件都可以访问到目前为止加载的任何文件中定义的私有variables。