在Clojure中使用命名空间的常见约定是什么?

我很难find在Clojure中使用命名空间的好build议和常见做法。 我意识到名称空间与Java包不一样,所以我试图梳理Clojure中的惯例,这似乎很难确定。

我想我有一个很好的主意,如何将function分成clj文件,甚至大致如何我想组织这些文件到目录。 但除此之外,我很难find我的开发环境的机制。 一些相互关联的问题:

  1. 对于Clojure命名空间,我是否会像使用Java程序包一样使用相同的唯一性约定? [即backwards-company-domain.project.subsystem]
  2. 我应该将文件保存在与我的命名空间相匹配的目录结构中吗? [ala Java]
  3. 如果我有多个名称空间,是否需要将我的所有代码编译到一个jar中,并将其添加到我的类path中以使其可访问?
  4. 每个命名空间应该编译成一个jar吗? 或者,我应该创build一个包含许多命名空间的clj代码的jar吗?

谢谢…

  1. 如果你认为它有帮助,我想这样可以,但是很多Clojure项目并没有这么做。 Compojure(使用顶级的组合和特定function的各种组合)*,Ring,Leiningen … Clojure本身使用clojure *(以及用于contrib库的clojure.contrib。*),但这是一个特例,我想。

  2. 是! 你绝对必须这样做,否则Clojure将无法find你的名字空间。 另外请注意,您不能在名称空间名称中使用下划线,或者在文件名中使用连字符,而在名称空间名称中使用连字符的任何位置,都必须在文件名中使用下划线(以便ns my.cool-project在一个名为cool_project.clj的文件叫做my )。

  3. 你需要确保你所有的东西都在类path上,但是不pipe它是在一个jar里面,还是在多个jar里面,在文件系统上是一个jar和目录的混合体。只要它服从正确的命名约定(你的观点2)你应该没问题。

    但是,如果没有特别的理由,不要提前编译,这可能会阻止你的代码在不同版本的Clojure上移植,除了稍微改进了加载时间之外,没有提供任何好处。

    您仍然需要使用AOT编译,特别是在某些Java互操作场景中 – 相关函数/macros的文档始终提到。 在clojure.contrib中有一些需要AOT的例子; 我从来没有需要它,所以我不能提供很多的细节。

  4. 我会说你应该使用jar子的function单位的代码。 例如Compojure和Ring可以打包成单个包含许多命名空间的单个jar子,这些命名空间一起组成整个包装。 此外,clojure.contrib明显打包成一个单独的jar与多个不相关的库; 但是这又可能是一个特例。

    另一方面,包含所有项目代码及其依赖项的单个jar可能偶尔会对部署有用。 如果你认为这样的事情可能对你有用,请查看Leiningen构build工具及其“uberjar”工具。

  1. 严格地说,并不是必须的,尽pipe许多Java项目也放弃了这个惯例,尤其是对于内部项目或私有API。 避免使用单段命名空间,这会导致在默认包中生成类文件。
  2. 是。

关于3和4,封装和AOT编译完全正交于命名空间惯例的问题。