Clojure 简单上手入门

官网: https://clojure.org

安装 lein

官网: https://leiningen.org, 下载 lein 脚本, 放到 /usr/local/bin 下, 添加可执行权限. 执行 lein version, 首次执行会下载 leiningen-2.9.8-standalone.jar, 放在 ~/.lein/self-installs. 如果自动下载失败, 可以手动下载, 然后放到指定的位置.

$ lein version
WARNING: You have $CLASSPATH set, probably by accident.
It is strongly recommended to unset this before proceeding.
Leiningen 2.9.8 on Java 1.8.0_131 Java HotSpot(TM) 64-Bit Server VM

看见如上版本号输出, 说明 lein 安装成功了. 输出有一个 WARNING, 虽然不影响使用, 但每次执行 lein 命令都会出现这个 WARNING, 看着有点糟心. 解决方案也很简单, 找到设置 $CLASSPATH 环境变量的地方, 注释掉!

REPL

$ lein repl
nREPL server started on port 65378 on host 127.0.0.1 - nrepl://127.0.0.1:65378
REPL-y 0.5.1, nREPL 0.8.3
Clojure 1.10.3
Java HotSpot(TM) 64-Bit Server VM 1.8.0_131-b11
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

user=> 1
1
user=> (println "Hello, World!")
Hello, World!
nil
user=> Bye for now!

创建 Hello World 项目

新建项目

$ lein new hello-world
Generating a project called hello-world based on the 'default' template.
The default template is intended for library projects, not applications.
To see other templates (app, plugin, etc), try `lein help new`.

加入版本控制

cd hello-world
git init
git add .
git commit -a -m 'init'

看一下有哪些文件

$ tree .
.
├── CHANGELOG.md
├── LICENSE
├── README.md
├── doc
│   └── intro.md
├── project.clj
├── resources
├── src
│   └── hello_world
│       └── core.clj
└── test
    └── hello_world
        └── core_test.clj

其中 src/hello_world/core.clj 文件中定义了 foo 函数, 内容如下

(ns hello-world.core)

(defn foo
  "I don't do a whole lot."
  [x]
  (println x "Hello, World!"))

接下来, 我们执行一下

$ lein repl
nREPL server started on port 65474 on host 127.0.0.1 - nrepl://127.0.0.1:65474
REPL-y 0.5.1, nREPL 0.8.3
Clojure 1.10.3
Java HotSpot(TM) 64-Bit Server VM 1.8.0_131-b11
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

hello-world.core=> (foo "Henry")
Henry Hello, World!
nil
hello-world.core=> Bye for now!

IntelliJ IDEA + Cursive

通过 IDEA 打开 hello-world 项目, 需要 Cursive 插件, 如果提示需要 licence, 可以到 Cursive 官网申请一个 Non-Commercial free licence.

lein run

$ lein run
No :main namespace specified in project.clj.

根据提示在 project.clj 文件中, 增加 :main hello-world.core 配置, 再次执行

$ lein run
Syntax error compiling at (/private/var/folders/k_/9tk7bt8j79b0857dk3w03ync0000gn/T/form-init2350240642557560559.clj:1:125).
Cannot find anything to run for: hello-world.core

Full report at:
/var/folders/k_/9tk7bt8j79b0857dk3w03ync0000gn/T/clojure-6739582287684991438.edn

修改 src/hello_world/core.clj 文件如下

(ns hello-world.core)

(defn -main
  "I don't do a whole lot."
  [& x]
  (println x "Hello, World!"))

再次执行

$ lein run
nil Hello, World!

lein uberjar 打包构建

$ lein uberjar
Warning: specified :main without including it in :aot.
Implicit AOT of :main will be removed in Leiningen 3.0.0.
If you only need AOT for your uberjar, consider adding :aot :all into your
:uberjar profile instead.
Compiling hello-world.core
Warning: The Main-Class specified does not exist within the jar. It may not be executable as expected. A gen-class directive may be missing in the namespace which contains the main method, or the namespace has not been AOT-compiled.
Created /private/tmp/hello-world/target/hello-world-0.1.0-SNAPSHOT.jar
Created /private/tmp/hello-world/target/hello-world-0.1.0-SNAPSHOT-standalone.jar

根据报错提示, 在 project.clj 中增加 :aot :all 配置.

修改 src/hello_world/core.clj 中的第一行为

(ns hello-world.core
  (:gen-class))

再次执行

$ lein uberjar
Compiling hello-world.core
Created /private/tmp/hello-world/target/hello-world-0.1.0-SNAPSHOT.jar
Created /private/tmp/hello-world/target/hello-world-0.1.0-SNAPSHOT-standalone.jar
$ java -jar target/hello-world-0.1.0-SNAPSHOT-standalone.jar
nil Hello, World!
$ java -jar target/hello-world-0.1.0-SNAPSHOT-standalone.jar Henry
(Henry) Hello, World!

升级依赖

Lein 默认使用了 Maven 和 Clojars 的官方源下载项目依赖, 在国内速度不是很理想, 可以通过配置镜像源的方式加速. 新增 vim ~/.lein/profiles.clj 配置文件, 内容如下

{
    :user {
        :mirrors {
            #"clojars" {
                :name "Clojar Mirror"
                :url "https://mirrors.tuna.tsinghua.edu.cn/clojars"
                :repo-manager true
            }
            #"central" {
                :name "Maven aliyun"
                :url "https://maven.aliyun.com/repository/public"
                :repo-manager true
            }
        }
    }
}

修改 project.clj 中的依赖配置为

:dependencies [[org.clojure/clojure "1.11.1"]]

再次执行 lein uberjar 命令.

参考资料

相关推荐