clojure – defn和defmacro之间有什么区别?

defn和defmacro之间有什么区别?函数和宏之间有什么区别?
defn定义了一个函数,defmacro定义了一个宏。

函数和宏之间的区别在于,在函数调用上首先对函数的参数进行求值,然后使用参数来求值函数的主体。

另一方面,宏描述了从一段代码到另一段代码的转换。任何评估发生在转换之后。

这意味着参数可以被多次评估或根本不被评估。作为示例或是宏。如果or的第一个参数为false,则永远不会计算第二个参数。如果或是一个函数,这是不可能的,因为参数将始终在函数运行之前进行评估。

这种情况的另一个后果是,在扩展宏之前,宏的参数不必是有效的表达式。例如,你可以定义一个宏mymacro,使(mymacro(12 23))扩展到(23 12),所以这将工作,即使(12 23)本身是废话。你不能使用函数,因为(12 23)将被评估,并导致一个错误,在函数运行之前。

一个小例子来说明区别:

(defmacro twice [e] `(do ~e ~e))
(twice (println "foo"))

宏两次获取列表(println“foo”)作为参数。然后将它转换为列表(do(println“foo”)(println“foo”))。这个新的代码是什么被执行。

(defn twice [e] `(do ~e ~e))
(twice (println "foo"))

这里println“foo”被立即评估。因为println返回nil,所以用nil作为参数调用两次。两次现在产生列表(do nil nil)并返回其结果。注意,这里(do nil nil)不会被计算为代码,它只是作为一个列表。

http://stackoverflow.com/questions/3667403/what-is-the-difference-between-defn-and-defmacro

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:clojure – defn和defmacro之间有什么区别?