Clojure

使用库

Clojure 通过其“库”功能提供代码加载和依赖项跟踪。库是包含在类路径中 Java 资源中的命名 Clojure 源代码单元。库通常会提供构成一个 Clojure 命名空间的完整定义集。

库约定

Clojure 定义了命名和构建库的约定。

  • 库名称是一个符号,通常包含由句点分隔的两个或多个部分。

  • 库的容器是一个 Java 资源,其类路径相关的路径是从库名称派生的。

    • 路径是一个字符串。

    • 库名称中的句点在路径中将被替换为斜杠。

    • 库名称中的连字符在路径中将被替换为下划线。

    • 路径可以以“.class”、“.clj”或“.cljc”结尾(请参见下面的库加载顺序)。

  • 库以“ns”形式开头,该形式

    • 创建与库名称相同的 Clojure 命名空间,以及

    • 声明其对 Java 类、Clojure 的核心功能和/或其他库的依赖关系。

Clojure 确保如果对“ns”的调用完成且未抛出异常,则已满足声明的依赖关系,并且它们提供的功能可用。

库示例

一个简单的库

(ns com.my-company.clojure.examples.my-utils
  (:import java.util.Date)
  (:use [clojure.string :only (join)])
  (:require [clojure.java.io :as jio]))
  • ns 形式命名库的命名空间并声明其依赖项。根据其名称,此库通常在类路径相关的路径中定义:com/my_company/clojure/examples/my_utils.clj(请注意句点到斜杠和连字符到下划线的转换)。

  • :import 子句声明此库对java.util.Date的使用,并使其可以使用未限定名称在该库中的代码中可用。

  • :use 子句声明对clojure.string库的依赖关系,仅用于其join函数。join可以在此库的代码中使用其未限定名称。

  • :require 子句声明对clojure.java.io库的依赖关系,并允许使用较短的命名空间别名jio来使用其成员。

前缀列表

库通常依赖于几个其他库,其完整名称共享一个共同的前缀。在对requireuse的调用中(以及在ns形式内的:require:use子句中),可以使用前缀列表提取并提供一次公共前缀。例如,以下两种形式是等效的

(require 'clojure.contrib.def 'clojure.contrib.except 'clojure.contrib.sql)
(require '(clojure.contrib def except sql))

创建命名空间:ns

确保库已加载:require use

列出已加载的库:loaded-libs

库加载顺序

库可以以编译(.class)或源(.clj.cljc)形式存在。在某些情况下,类路径上可能存在其中一个甚至所有这些。库将根据以下规则从其中一个加载:

  • 始终优先选择.class文件而不是源文件,除非源文件的时间戳比.class文件新,在这种情况下,优先选择源文件。

  • 始终优先选择.clj(特定于平台的文件)而不是.cljc(跨平台通用)。

第二个规则允许库作者同时提供库的可移植通用定义,以及提供覆盖可移植版本的特定于平台的库,以执行利用主机平台的操作。