macros - 如何在宏调用中使用参数?

标签 macros lisp common-lisp sbcl

我定义了以下简单的宏:

 (defmacro define-class (class-name)
  `(defclass ,class-name ()()))

现在我想在下面的函数中使用它:

(defun create-data (mode)
  (define-class mode))

编译完最后一个函数后,我得到以下消息,变量 MODE 已定义但从未使用过

当我执行创建类“myclass”的函数时,我得到的是创建一个类型为“mode”的类:

 (create-data 'myclass)
 #<STANDARD-CLASS MODE>

好像我的论点没有被使用?我怎样才能让 create-data 函数使用参数?

最佳答案

defclass 不是函数而是宏。它使用源代码中提供的名称(在您的情况下为模式),它与您的变量 mode 不同。事实上,某些 CL 实现会警告您从未使用参数 mode

您可以对其进行宏扩展 (macroexpand '(defclass mode ()())) 以检查它在您的实现中变成了什么。我在 CLISP 中得到了这个(我稍微清理了一下):

(progn
  (eval-when (compile load eval)
    (apply #'ensure-class 
           'mode ; notice mode is quoted
           :direct-superclasses (list) 
           :direct-slots (list) 
           :metaclass clos::<standard-class>
           (append '(:fixed-slot-locations nil) 
                    (list :direct-default-initargs nil 
                          :documentation nil 
                          :generic-accessors 't))))
  (find-class 'mode)) ; notice mode is quoted

扩展依赖于实现,但结果都是一样的。 mode 是正在定义的类的名称,而不是您作为参数传递的名称。

您应该使用 (define-class myclass) 而不是 (create-data 'myclass)

关于macros - 如何在宏调用中使用参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30476437/

相关文章:

c++ - 预处理字符串连接

unit-testing - 如何在 clojure 中模拟宏以进行测试?

c++ - #为不同的上下文定义 “static”的宏

string - 口齿不清比较

graph - Common Lisp 中的反转有向图

android - Cocos2d-x 项目中的宏

emacs - 无法将目录及其所有子目录添加到 Emacs 中的加载路径

lisp - 如何在方案中找到列表的中位数

c++ - 从 Common Lisp 调用 C++(不是 C)?

list - 普通口齿不清 : How to implement reduce