Clojure

使用函式庫

Clojure 透過其「函式庫」機制提供程式碼載入和相依性追蹤。函式庫是 Clojure 原始碼的命名單元,包含在類別路徑中的 Java 資源中。函式庫通常會提供組成一個 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(跨平台通用)。

第二個規則允許函式庫作者同時發布可攜式共用函式庫定義,以及覆寫可攜式版本以執行利用主機平台的特定於平台函式庫。