如何在宏调用中使用参数?
How to use a parameter in a macro call?
我定义了以下简单的宏:
(defmacro define-class (class-name)
`(defclass ,class-name ()()))
现在我想在以下函数中使用它:
(defun create-data (mode)
(define-class mode))
编译最后一个函数后,我得到以下消息,变量 MODE 已定义但从未使用过。
当我执行创建 class "myclass" 的函数时,我反而创建了 class 类型 "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
是正在定义的 class 的名称,而不是您作为参数传递的名称。
您应该使用 (define-class myclass)
而不是 (create-data 'myclass)
。
我会用这样的东西:
CL-USER 86 > (defmacro define-class (class-name)
`(defclass ,class-name ()()))
DEFINE-CLASS
CL-USER 87 > (defun create-data (mode)
(funcall (compile nil `(lambda ()
(define-class ,mode)))))
CREATE-DATA
CL-USER 88 > (create-data 'bar)
#<STANDARD-CLASS BAR 402016CC73>
以上使用代码生成和内置编译器。
我定义了以下简单的宏:
(defmacro define-class (class-name)
`(defclass ,class-name ()()))
现在我想在以下函数中使用它:
(defun create-data (mode)
(define-class mode))
编译最后一个函数后,我得到以下消息,变量 MODE 已定义但从未使用过。
当我执行创建 class "myclass" 的函数时,我反而创建了 class 类型 "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
是正在定义的 class 的名称,而不是您作为参数传递的名称。
您应该使用 (define-class myclass)
而不是 (create-data 'myclass)
。
我会用这样的东西:
CL-USER 86 > (defmacro define-class (class-name)
`(defclass ,class-name ()()))
DEFINE-CLASS
CL-USER 87 > (defun create-data (mode)
(funcall (compile nil `(lambda ()
(define-class ,mode)))))
CREATE-DATA
CL-USER 88 > (create-data 'bar)
#<STANDARD-CLASS BAR 402016CC73>
以上使用代码生成和内置编译器。