Hello World #

一、第一个Clojure程序 #

1.1 使用REPL #

最简单的方式是在REPL中运行:

bash
clj
clojure
user=> (println "Hello, World!")
Hello, World!
nil

1.2 创建项目 #

使用Leiningen创建项目:

bash
lein new hello-world
cd hello-world

1.3 编写代码 #

编辑 src/hello_world/core.clj

clojure
(ns hello-world.core)

(defn -main []
  (println "Hello, World!"))

1.4 运行程序 #

bash
lein run

输出:

text
Hello, World!

二、程序结构解析 #

2.1 命名空间声明 #

clojure
(ns hello-world.core)
  • ns 定义命名空间
  • hello-world.core 是命名空间名称
  • 对应文件路径 src/hello_world/core.clj

2.2 函数定义 #

clojure
(defn -main []
  (println "Hello, World!"))

分解说明:

部分 含义
defn 定义函数的宏
-main 函数名(主函数约定)
[] 参数向量(空表示无参数)
(println ...) 函数体

2.3 S表达式 #

Clojure使用S表达式(S-expression)语法:

clojure
(操作符 操作数1 操作数2 ...)

示例

clojure
(+ 1 2 3)

(println "Hello")

(str "Hello" " " "World")

2.4 前缀表示法 #

Clojure使用前缀表示法(波兰表示法):

clojure
(+ 1 2)

(- 10 3)

(* 2 3 4)

(/ 10 2)

优势

  • 无运算符优先级问题
  • 支持多参数
  • 一致性强

三、语法基础 #

3.1 注释 #

clojure
(println "Hello")

(println "World")

(comment
  (println "This is not executed")
  (+ 1 2 3))

3.2 数据字面量 #

clojure
42
3.14
"Hello"
\A
true
false
nil
:keyword
'symbol
'(1 2 3)
[1 2 3]
{:a 1 :b 2}
#{1 2 3}

3.3 符号命名规则 #

clojure
(def my-variable 10)
(def my-function +)
(def *important* true)
(def ->json identity)
(defn my-function? [x] true)

约定

  • 使用kebab-case(短横线分隔)
  • 谓词函数以 ? 结尾
  • 危险操作以 ! 结尾
  • 常量使用 *星号*

3.4 块表达式 #

do 用于组合多个表达式:

clojure
(do
  (println "Step 1")
  (println "Step 2")
  (println "Step 3")
  "done")

返回最后一个表达式的值。

四、函数定义详解 #

4.1 基本函数定义 #

clojure
(defn greet [name]
  (str "Hello, " name "!"))

(greet "Clojure")

4.2 多参数函数 #

clojure
(defn add [a b]
  (+ a b))

(defn greet-person [first-name last-name]
  (str "Hello, " first-name " " last-name))

(greet-person "John" "Doe")

4.3 可变参数 #

clojure
(defn sum [& numbers]
  (apply + numbers))

(sum 1 2 3 4 5)

(defn greet-all [greeting & names]
  (str greeting ", " (clojure.string/join ", " names)))

(greet-all "Hello" "Alice" "Bob" "Carol")

4.4 多参数列表 #

clojure
(defn greet
  ([name]
   (greet "Hello" name))
  ([greeting name]
   (str greeting ", " name "!")))

(greet "Alice")
(greet "Hi" "Bob")

4.5 文档字符串 #

clojure
(defn square
  "Returns the square of a number.
   Usage: (square 5) => 25"
  [x]
  (* x x))

(doc square)

五、变量定义 #

5.1 def #

def 用于定义全局变量:

clojure
(def pi 3.14159)

(def message "Hello, World!")

(defn circle-area [r]
  (* pi (* r r)))

5.2 let #

let 用于局部绑定:

clojure
(let [x 10
      y 20]
  (+ x y))

(let [a 1
      b (+ a 2)
      c (+ b 3)]
  [a b c])

5.3 常量 #

clojure
(def ^:const MAX-VALUE 100)
(def ^:const DEFAULT-TIMEOUT 5000)

六、执行方式 #

6.1 REPL执行 #

bash
clj
clojure
user=> (defn hello [] (println "Hello!"))
user=> (hello)
Hello!
nil

6.2 脚本执行 #

创建 script.clj

clojure
(println "Running as script")
(println (+ 1 2 3))

执行:

bash
clj -M script.clj

6.3 主函数执行 #

project.clj 中指定:

clojure
(defproject hello "0.1.0"
  :main hello.core)

运行:

bash
lein run

6.4 编译执行 #

bash
lein uberjar
java -jar target/hello-0.1.0-standalone.jar

七、代码组织 #

7.1 命名空间 #

clojure
(ns my-app.core
  (:require [clojure.string :as str])
  (:use [clojure.set])
  (:import [java.util Date]))

(defn current-time []
  (str (Date.)))

7.2 require #

clojure
(ns my-app.core
  (:require [clojure.string :as str]))

(str/upper-case "hello")

(ns my-app.core
  (:require [clojure.string :refer [upper-case lower-case]]))

(upper-case "hello")

7.3 import #

clojure
(ns my-app.core
  (:import [java.util Date ArrayList]
           [java.io File]))

(defn now []
  (Date.))

(defn list-files [path]
  (.listFiles (File. path)))

八、REPL开发流程 #

8.1 交互式开发 #

clojure
user=> (defn greet [name] (str "Hello, " name))
#'user/greet

user=> (greet "World")
"Hello, World"

user=> (defn greet [name] (str "Hi, " name "!"))
#'user/greet

user=> (greet "World")
"Hi, World!"

8.2 加载文件 #

clojure
user=> (load-file "src/my_app/core.clj")

user=> (use 'my-app.core :reload)

8.3 查看文档 #

clojure
user=> (doc println)

user=> (find-doc "string")

user=> (source map)

九、常见错误 #

9.1 括号不匹配 #

clojure
(defn add [a b]
  (+ a b))

(defn add [a b]
  (+ a b))

9.2 符号未定义 #

clojure
user=> (unknown-symbol)
Syntax error compiling at (REPL:0:0).
Unable to resolve symbol: unknown-symbol in this context

9.3 参数数量错误 #

clojure
user=> (+ 1)
ArityException Wrong number of args (1) passed to: core/+

9.4 类型错误 #

clojure
user=> (+ 1 "a")
ClassCastException java.lang.String cannot be cast to java.lang.Number

十、总结 #

第一个Clojure程序的关键点:

  1. S表达式(操作符 操作数...)
  2. 前缀表示法:无优先级问题
  3. 函数定义defn 名称 [参数] 函数体
  4. 命名空间ns 声明

Clojure程序特点:

  • 语法简洁统一
  • 代码即数据
  • 函数是一等公民
  • 交互式开发体验

准备好深入学习REPL交互环境了吗?让我们继续!

最后更新:2026-03-27