user=> (macroexpand '(when (pos? a) (println "positive") (/ b a)))
(if (pos? a) (do (println "positive") (/ b a)))
Clojure 拥有一个可编程的宏系统,允许用户代码扩展编译器。宏可以用于定义语法结构,这些结构在其他语言中需要基本类型或内置支持。许多 Clojure 的核心结构实际上并不是基本类型,而是普通的宏。
user=> (macroexpand '(when (pos? a) (println "positive") (/ b a)))
(if (pos? a) (do (println "positive") (/ b a)))
其他宏以有用的方式重新排列形式,例如 ->
宏,它递归地将每个表达式插入为下一个表达式的第一个参数。
user=> (-> {} (assoc :a 1) (assoc :b 2))
{:b 2, :a 1}
user=> (macroexpand '(-> {} (assoc :a 1) (assoc :b 2)))
(assoc (assoc {} :a 1) :b 2)
在 defmacro 内部可以使用两个特殊变量进行更高级的用法。
&form
- 正在调用的实际形式(作为数据)。
&env
- 宏展开时局部绑定的映射。env 映射是从符号到包含该绑定的编译器信息的对象的映射。
以下所有宏都在 API 页面中进行了说明。许多宏也在主题页面上进行了讨论,如注释所示。
创建宏: defmacro definline macroexpand-1 macroexpand
分支: and or when when-not when-let when-first if-not if-let cond condp
循环(另请参阅 序列): for doseq dotimes while
使用变量(另请参阅 变量和环境): ns declare defn defmacro definline defmethod defmulti defn- defonce defstruct
以不同的方式排列代码: .. doto ->
动态作用域(另请参阅 变量和环境): binding locking time with-in-str with-local-vars with-open with-out-str with-precision
创建延迟事物(另请参阅 序列): lazy-seq lazy-cat delay
Java 交互 宏: .. amap areduce gen-class gen-interface proxy proxy-super memfn
记录代码: assert comment doc
事务: dosync io!