【发布时间】:2013-06-10 04:48:17
【问题描述】:
我很难准确理解宏扩展的工作原理。 elisp解释器处理这两个sn-ps的代码有什么区别?
(defmacro foo (arg)
(message "arg is: %s" arg))
(foo "bar")
和:
(defmacro foo (arg)
`(message "arg is: %s" ,arg))
(foo "bar")
【问题讨论】:
我很难准确理解宏扩展的工作原理。 elisp解释器处理这两个sn-ps的代码有什么区别?
(defmacro foo (arg)
(message "arg is: %s" arg))
(foo "bar")
和:
(defmacro foo (arg)
`(message "arg is: %s" ,arg))
(foo "bar")
【问题讨论】:
message 既显示一条消息,又返回它。(defconst zzz 123)
(defmacro zzz1 (arg)
`(insert (format "arg is: %s" ,arg)))
(defmacro zzz2 (arg)
(insert (format "arg is: %s" arg)))
在 3 种形式之后使用 C-x C-e 评估上面的代码。
现在评估这些:
(zzz1 zzz)
解释器...
zzz1的宏函数
(insert (format "arg is: %s" zzz))的形式
"arg is: 123" 插入当前缓冲区,并返回nil(在底部的回显区域中看到)(zzz2 zzz)
解释器...
zzz2的宏函数
"arg is: zzz"插入当前缓冲区并返回nil
nil 评估为nil(在底部可以看到回声)这里最重要的“要点”是宏只是在(编译器的)解释器启动之前对代码进行操作的函数。
这些函数的参数未经计算(即在zzz1 和zzz2 中,arg 是zzz,而不是123)。
它们像任何其他 lisp 函数一样被评估(例如,它们的主体中可以有宏形式;主体包裹在隐式 progn 中;&c)。
它们的返回值由解释器评估而不是原始形式。
【讨论】:
(zzz2 zzz) 被 (insert (format "arg is: %s" zzz))(宏的主体,但替换了 args)替换,然后进行了评估。