為了理解 Clojure 的基本語法,讓我們先來看一個(gè)簡單的 Hello World 程序。
在一個(gè)完整的 Clojure 程序中編寫“Hello world”。 下面是一個(gè)例子。
(ns clojure.examples.hello (:gen-class)) (defn hello-world [] (println "Hello World")) (hello-world)
上述例子需要注意以下事項(xiàng):
程序?qū)⒈粚懭胍粋€(gè)名為 main.clj 的文件中。 擴(kuò)展名 'clj' 是 clojure 代碼文件的擴(kuò)展名。 在上面的示例中,文件的名稱稱為 main.clj。
'defn' 關(guān)鍵字用于定義一個(gè)函數(shù)。 我們將在另一章詳細(xì)介紹功能。 但是現(xiàn)在,知道我們正在創(chuàng)建一個(gè)名為 helloworld 的函數(shù),它將擁有我們的主要 Clojure 代碼。
在我們的 Clojure 代碼中,我們使用'println'語句將“Hello World”打印到控制臺(tái)輸出。
然后我們調(diào)用 hello-world 函數(shù),它又運(yùn)行 'println' 語句。
上述程序產(chǎn)生以下輸出:
Hello World
任何語句的一般形式需要在大括號(hào)中求值,如下面的示例所示:
(+ 1 2)
在上面的示例中,整個(gè)表達(dá)式用大括號(hào)括起來。 上面語句的輸出是3. +運(yùn)算符就像Clojure中的一個(gè)函數(shù),用于添加數(shù)字。 1和2的值稱為函數(shù)的參數(shù)。
讓我們考慮另一個(gè)例子。 在本例中,'str'是用于連接兩個(gè)字符串的運(yùn)算符。 字符串“Hello”和“World”用作參數(shù)。
(str "Hello" "World")
如果我們結(jié)合上面的兩個(gè)語句并編寫一個(gè)程序,它將如下所示。
(ns clojure.examples.hello (:gen-class)) (defn Example [] (println (str "Hello" "World")) (println (+ 1 2))) (Example)
上述程序產(chǎn)生以下輸出:
Hello World 3
命名空間用于定義在 Clojure 中定義的模塊之間的邏輯邊界。
這定義了當(dāng)前 Clojure 代碼所在的當(dāng)前命名空間。
*ns*
在 REPL 命令窗口中運(yùn)行以下命令。
*ns*
當(dāng)我們運(yùn)行上面的命令時(shí),輸出將取決于當(dāng)前的命名空間是什么。 以下是輸出的示例。 Clojure 代碼的命名空間是
clojure.examples.hello (ns clojure.examples.hello (:gen-class)) (defn Example [] (println (str "Hello World")) (println (+ 1 2))) (Example)
Clojure 代碼封裝在庫中。 每個(gè) Clojure 庫都屬于一個(gè)命名空間,類似于 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' 關(guān)鍵字來導(dǎo)入命名空間 clojure.java.io,它具有輸入/輸出功能所需的所有功能。 因?yàn)槲覀儧]有所需的庫,所以我們可以在上面的代碼中使用 'file' 函數(shù)。
注釋用于記錄您的代碼。 單行注釋通過使用;; 在該行的任何位置。 下面是一個(gè)例子。
(ns clojure.examples.hello (:gen-class)) ;; This program displays Hello World (defn Example [] (println "Hello World")) (Example)
在 Clojure 中,可以使用彎曲或方括號(hào)括號(hào)來分割或分隔語句。
下面是兩個(gè)例子。
(ns clojure.examples.hello (:gen-class)) ;; This program displays Hello World (defn Example [] (println (+ 1 2 3))) (Example)
上述程序產(chǎn)生以下輸出:
6
以下是另一個(gè)例子。
(ns clojure.examples.hello (:gen-class)) ;; This program displays Hello World (defn Example [] (println [+ 1 2 3])) (Example)
上述程序產(chǎn)生以下輸出:
[#object[clojure.core$_PLUS_ 0x10f163b "clojure.core$_PLUS_@10f163b"] 1 2 3]
空格可以在 Clojure 中用于拆分語句的不同組件,這樣可以讓代碼更加的清晰。也可以和逗號(hào) (,) 運(yùn)算符一起使用。
例如,以下兩個(gè)語句是等效的,并且兩個(gè)語句的輸出將是 15。
(+ 1 2 3 4 5) (+ 1, 2, 3, 4, 5)
盡管 Clojure 忽略逗號(hào),但逗號(hào)的使用讓程序更便于閱讀。
例如,如果你有一個(gè)哈希映射,如下(def a-map {:a 1:b 2:c 3})并要求在 REPL 窗口中的值,Clojure 將打印輸出為{:a 1, :b 2,:c 3}。
結(jié)果更容易閱讀,特別是如果你查看大量的數(shù)據(jù)。
在 Clojure 中,符號(hào)等同于其他編程語言中的標(biāo)識(shí)符。 但與其他編程語言不同,編譯器將符號(hào)視為實(shí)際的字符串值。 由于符號(hào)是一個(gè)值,符號(hào)可以存儲(chǔ)在集合中,作為參數(shù)傳遞給函數(shù)等,就像任何其他對(duì)象一樣。
符號(hào)只能包含字母數(shù)字字符和“* +! /。 : - _?',但不能以數(shù)字或冒號(hào)開頭。
以下是符號(hào)的有效示例:
tutorial-point! TUTORIAL +tutorial+
最后,讓我們談?wù)勔粋€(gè) Clojure 項(xiàng)目的典型項(xiàng)目結(jié)構(gòu)。 由于 Clojure 代碼在 Java 虛擬機(jī)上運(yùn)行,因此 Clojure 中的大部分項(xiàng)目結(jié)構(gòu)與在 java 項(xiàng)目中發(fā)現(xiàn)的類似。 以下是 Eclipse 中針對(duì) Clojure 項(xiàng)目的示例項(xiàng)目結(jié)構(gòu)的快照。
關(guān)于項(xiàng)目結(jié)構(gòu),有一下幾個(gè)關(guān)鍵的地方需要注意:
demo_1 - 這是 Clojure 代碼文件放在其中的包。
core.clj - 這是主要的 Clojure 代碼文件,它將包含Clojure應(yīng)用程序的代碼。
Leiningen 文件夾包含像運(yùn)行任何基于 Clojure 的應(yīng)用程序所需的 clojure-1.6.0.jar 文件。
pom.properties 文件將包含諸如 groupId,artifactId和 Clojure 項(xiàng)目版本等信息。
project.clj 文件包含關(guān)于 Clojure 應(yīng)用程序本身的信息。 以下是項(xiàng)目文件內(nèi)容的示例。
(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"]])
更多建議: