namespaces - 将 Clojure 命名空间拆分为多个文件

标签 namespaces clojure compilation

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

最佳答案

概述

当然可以,事实上 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>那个函数。

私有(private)变量

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

关于namespaces - 将 Clojure 命名空间拆分为多个文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4690758/

相关文章:

C# 命名空间 : how to follow standards without causing annoying conflicts?

php - 我可以在运行时识别我的 PHP 是否支持命名空间吗?

clojure - 从Clojure中的序列中获取元素

clojure - 如何每次从重复的函数中获取不同的值?

clojure - 帮助我了解 Clojure 中如何处理不变性和运行时间之间的冲突

go - 使用动态(config.toml)配置文件发送 Golang 二进制文件

c++ - 没有实现文件时包含头文件?

java - 在 Minecraft mod 中修改 .class 文件

javascript - 在 JavaScript 中,为常规元素和命名空间元素分配类名是否不同?

c++ - 使用预制命名空间 (C++) 的范围