将 Clojure 命名空间拆分为多个文件 [英] Splitting a Clojure namespace over multiple files

查看:17
本文介绍了将 Clojure 命名空间拆分为多个文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用 :gen-class 进行提前编译时,是否可以将 Clojure 命名空间拆分为多个源文件?(:main true)(defn- ...) 如何发挥作用?

Is it possible to split a Clojure namespace over multiple source files when doing ahead-of-time compilation with :gen-class? How do (:main true) and (defn- ...) come into play?

推荐答案

概述

当然可以,事实上 clojure.core 命名空间本身就是这样拆分的,并提供了一个很好的模型,您可以通过查看 src/clj/clojure 来遵循:

Overview

Certainly you can, in fact clojure.core namespace itself is split up this way and provides a good model which you can follow by looking in src/clj/clojure:

core.clj
core_deftype.clj
core_print.clj
core_proxy.clj
..etc..

所有这些文件都参与构建了单个 clojure.core 命名空间.

All these files participate to build up the single clojure.core namespace.

其中一个是主文件,命名以匹配命名空间名称,以便当有人在 :use:require 中提到它时可以找到它.在这种情况下,主文件是 clojure/core.clj,它以 ns 形式开头.这是您应该放置所有命名空间配置的地方,而不管您的其他哪些文件可能需要它们.这通常也包括 :gen-class,例如:

One of these is the primary file, named to match the namespace name so that it will be found when someone mentions it in a :use or :require. In this case the main file is clojure/core.clj, and it starts with an ns form. This is where you should put all your namespace configuration, regardless of which of your other files may need them. This normally includes :gen-class as well, so something like:

(ns my.lib.of.excellence
  (:use [clojure.java.io :as io :only [reader]])
  (:gen-class :main true))

然后在您的主文件中的适当位置(最常见的是在最后)使用 load 来引入您的帮助文件.在 clojure.core 中,它看起来像这样:

Then at appropriate places in your primary file (most commonly all at the end) use load to bring in your helper files. In clojure.core it looks like this:

(load "core_proxy")
(load "core_print")
(load "genclass")
(load "core_deftype")
(load "core/protocols")
(load "gvec")

请注意,您不需要当前目录作为前缀,也不需要 .clj 后缀.

Note that you don't need the current directory as a prefix, nor do you need the .clj suffix.

每个帮助文件应该首先声明它们正在帮助的命名空间,但应该使用 in-ns 函数来实现.所以对于上面的示例命名空间,帮助文件都将以:

Each of the helper files should start by declaring which namespace they're helping, but should do so using the in-ns function. So for the example namespace above, the helper files would all start with:

(in-ns 'my.lib.of.excellence)

仅此而已.

因为所有这些文件都在构建单个命名空间,所以您定义的每个函数都可以在任何主文件或帮助文件中.这当然意味着你可以在任何你喜欢的文件中定义你的 gen-class 函数:

Because all these files are building a single namespace, each function you define can be in any of the primary or helper files. This of course means you can define your gen-class functions in any file you'd like:

(defn -main [& args]
  ...)

请注意,Clojure 的正常定义顺序规则仍然适用于所有函数,因此您需要确保在尝试使用之前加载了函数定义的任何文件.em> 那个函数.

Note that Clojure's normal order-of-definition rules still apply for all functions, so you need to make sure that whatever file defines a function is loaded before you try to use that function.

您还询问了定义命名空间私有函数的 (defn- foo ...) 形式.像这样定义的函数以及其他 :private 变量在定义它们的命名空间内是可见的,因此主文件和所有帮助文件都可以访问在加载的任何文件中定义的私有变量到目前为止.

You also asked about the (defn- foo ...) form which defines a namespace-private function. Functions defined like this as well as other :private vars are visible from within the namespace where they're defined, so the primary and all helper files will have access to private vars defined in any of the files loaded so far.

这篇关于将 Clojure 命名空间拆分为多个文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆