我也有 Java 背景,还有相当多的 Ruby 和一点 Go。这是我目前正在做的事情,大约一个月后使用 Clojure:
- 我将命名空间视为一个语义单元,它是为特定目的组合在一起的代码,例如数据类型及其上的操作。
我有两个命名空间与文件的约定:
- 对于可以舒适地放入一个文件的小型单元(我使用 ~1000 行作为文件拆分的限制),每个文件都有一个命名空间,目录路径加上文件名与命名空间相同。我认为这在 Java 中是一件好事,它使从文件中查找名称空间变得轻而易举,反之亦然。
- 对于需要多个文件的较大单元,我使用 Go 约定:命名空间与目录路径匹配,并且目录中的所有文件共享同一个命名空间。在这些情况下,我通常会分配一个具有固定名称('main')的主文件,用于加载并与其他文件交互。
作为命名空间示例,我有一个解析器,它读取格式并将其转换为 HTML。我有一个用于解析器(语义单元)的命名空间,目录中的几个文件按子功能拆分:Lexer、解析器、HTML 转换和一个包含使用解析器的主要公共 API 的主文件。
我不会自动为每种数据类型使用一个命名空间,这取决于数据类型的范围。如果它是一个大的,也许。但是对于像 Point 这样的具有两个字段和几个函数的数据类型,我宁愿将它包含在像 Geometry 这样更通用的命名空间中。
需要与使用:
- 几乎在任何地方都需要一个适当的短别名。
- 这也允许重用核心名称:我的专用树数据类型具有操作“get”以适应映射;使用 require 没有冲突:“get”是 Clojure 核心 get,“tree/get”是我的数据类型。
- 我仅将“使用”用于我认为的“核心扩展”,例如当我制作自己的“map-if”时,它是将映射和过滤器合二为一。