Clojure - 基本語法



為了理解 Clojure 的基本語法,讓我們先來看一個簡單的 Hello World 程式。

完整的 Hello World 程式

編寫一個完整的 Clojure 程式來列印 ‘Hello world’。以下是一個例子。

示例

(ns clojure.examples.hello
   (:gen-class))
(defn hello-world []
   (println "Hello World"))
(hello-world)

關於上述程式需要注意以下幾點。

  • 程式將寫入名為 main.clj 的檔案中。副檔名 ‘clj’ 是 Clojure 程式碼檔案的副檔名。在上面的例子中,檔名叫做 main.clj。

  • ‘defn’ 關鍵字用於定義函式。我們將在另一章詳細介紹函式。但現在,請知道我們正在建立一個名為 helloworld 的函式,其中包含我們的主要 Clojure 程式碼。

  • 在我們的 Clojure 程式碼中,我們使用 ‘println’ 語句將“Hello World”列印到控制檯輸出。

  • 然後我們呼叫 hello-world 函式,該函式依次執行 ‘println’ 語句。

上述程式產生以下輸出。

輸出

Hello World

語句的一般形式

任何語句的一般形式都需要在大括號中進行計算,如下例所示。

(+ 1 2)

在上面的例子中,整個表示式都用大括號括起來。上述語句的輸出結果是 3。+ 運算子在 Clojure 中充當函式,用於數字的加法。1 和 2 的值被稱為函式引數

讓我們考慮另一個例子。在這個例子中,‘str’ 是用於連線兩個字串的運算子。字串“Hello”和“World”用作引數。

(str "Hello" "World")

示例

如果我們將上述兩個語句組合起來編寫一個程式,它將如下所示。

(ns clojure.examples.hello
   (:gen-class))
(defn Example []
   (println (str "Hello World"))
   (println (+ 1 2)))
(Example)

輸出

上述程式產生以下輸出。

Hello World
3

名稱空間

名稱空間用於定義 Clojure 中定義的模組之間的邏輯邊界。

當前名稱空間

這定義了當前 Clojure 程式碼所在的當前名稱空間。

語法

*ns*

示例

在 REPL 命令視窗中執行以下命令。

*ns*

輸出

當我們執行上述命令時,輸出將取決於當前名稱空間。以下是一個輸出示例。Clojure 程式碼的名稱空間是:

clojure.examples.hello

(ns clojure.examples.hello
   (:gen-class))
(defn Example []
   (println (str "Hello World"))
   (println (+ 1 2)))
(Example)

Clojure 中的 Require 語句

Clojure 程式碼打包在庫中。每個 Clojure 庫都屬於一個名稱空間,類似於 Java 包。您可以使用 ‘Require’ 語句載入 Clojure 庫。

語法

(require quoted-namespace-symbol)

示例

以下是用法示例。

(ns clojure.examples.hello
   (:gen-class))
(require ‘clojure.java.io’)
(defn Example []
   (.exists (file "Example.txt")))
(Example)

在上面的程式碼中,我們使用 ‘require’ 關鍵字匯入名稱空間 clojure.java.io,該名稱空間包含輸入/輸出功能所需的所有函式。由於我們沒有所需的庫,我們可以在上面的程式碼中使用 ‘file’ 函式。

Clojure 中的註釋

註釋用於記錄您的程式碼。單行註釋透過在行的任何位置使用 ;; 來標識。以下是一個例子。

示例

(ns clojure.examples.hello
   (:gen-class))

;; This program displays Hello World
(defn Example []
   (println "Hello World"))
(Example)

分隔符

在 Clojure 中,可以使用圓括號或方括號來分割或分隔語句。

示例

以下是兩個例子。

(ns clojure.examples.hello
   (:gen-class))

;; This program displays Hello World
(defn Example []
   (println (+ 1 2 3)))
(Example)

輸出

上述程式產生以下輸出。

6

示例

以下另一個例子。

(ns clojure.examples.hello
   (:gen-class))

;; This program displays Hello World
(defn Example []
   (println [+ 1 2 3]))
(Example)

輸出

上述程式產生以下輸出。

[#object[clojure.core$_PLUS_ 0x10f163b "clojure.core$_PLUS_@10f163b"] 1 2 3]

空格

空格可以在 Clojure 中用於分割語句的不同元件以提高畫質晰度。這可以透過逗號 (,) 運算子來實現。

例如,以下兩個語句是等效的,並且兩個語句的輸出都將是 15。

(+ 1 2 3 4 5)
(+ 1, 2, 3, 4, 5)

儘管 Clojure 忽略逗號,但有時它會使用逗號來使程式設計師更容易閱讀。

例如,如果您有一個類似於以下的雜湊對映 (def a-map {:a 1 :b 2 :c 3}) 並請求在 REPL 視窗中檢視其值,Clojure 將輸出為 {:a 1, :b 2, :c 3}。

結果更容易閱讀,尤其是在檢視大量資料時。

符號

在 Clojure 中,符號相當於其他程式語言中的識別符號。但與其他程式語言不同的是,編譯器將符號視為實際的字串值。由於符號是一個值,因此符號可以像任何其他物件一樣儲存在集合中,作為引數傳遞給函式等。

符號只能包含字母數字字元和 ‘* + ! / . : - _ ?’,但不能以數字或冒號開頭。

以下是符號的有效示例。

tutorial-point!
TUTORIAL
+tutorial+

Clojure 專案結構

最後,讓我們討論一下 Clojure 專案的典型專案結構。由於 Clojure 程式碼執行在 Java 虛擬機器上,因此 Clojure 中的大多數專案結構都與在 Java 專案中找到的結構類似。以下是 Eclipse 中 Clojure 專案的示例專案結構快照。

Basic Syntax

關於上述程式結構,需要注意以下關鍵事項。

  • demo_1 - 這是放置 Clojure 程式碼檔案的包。

  • core.clj - 這是主要的 Clojure 程式碼檔案,其中將包含 Clojure 應用程式的程式碼。

  • Leiningen 資料夾包含諸如 clojure-1.6.0.jar 之類的檔案,這些檔案是執行任何基於 Clojure 的應用程式所必需的。

  • pom.properties 檔案將包含諸如 groupId、artifactId 和 Clojure 專案的版本之類的資訊。

  • project.clj 檔案包含有關 Clojure 應用程式本身的資訊。以下是專案檔案內容的示例。

(defproject demo-1 "0.1.0-SNAPSHOT"
   :description "FIXME: write description"
   :url "http://example.com/FIXME"
   :license {
      :name "Eclipse Public License"
      :url "http://www.eclipse.org/legal/epl-v10.html"
   }
   :dependencies [[org.clojure/clojure "1.6.0"]])
廣告