我刚开始使用宏并制作了一个简单的宏来从列表中返回最大数量。
(defmacro macro-max [list] (apply max list))
如果我制作一个函数来做同样的事情,它会。
(defn macro-max [list] (apply max list))
我只是在探索Clojure,所以我知道的不多。
对于专家来说,我可能听起来很傻,但看起来我几乎可以定义一个函数而不是一个宏。
最佳答案
除非需要,否则当您不想评估您的论点时,差异就会变得栩栩如生。
考虑这个例子:
(defn unless [pred body]
(when (not pred)
body))
这不起作用,因为函数的参数会被急切地求值。所以body一直在运行,如下图:
(unless (zero? 2)
(prn "Not zero!"))
;; "Not zero!"
(unless (zero? 0)
(prn "Not zero!"))
;; "Not zero!"
上面的两个执行都打印“非零!”,这显然是错误的。
写我们的唯一途径
unless
实用程序是通过使用宏:(defmacro unless [pred body]
`(when (not ~pred)
~@body))
现在,如果我们尝试一下,我们会看到它按预期工作:
(unless (zero? 2)
(prn "Not zero!"))
;; "Not zero!"
(unless (zero? 0)
(prn "Not zero!"))
;; this prints nothing
宏仅在开发人员决定时评估其参数。
您会注意到宏中有一些特殊字符,例如`、~ 和~@。它们分别代表语法引用、取消引用和取消引用拼接,并解释 here .
我建议你研究这些符号。
希望这可以帮助。
关于clojure - 在 Clojure 中,宏与函数有何不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16009015/