在CLOS上创建类时,我多次遇到相同的模式:
(defclass class-name ()
((field-1
:initarg field-1
:initform some-value
:accessor field-1)
(field-2
:initarg field-2
:initform another-value
:accessor field-2)
(...)
(field-n
:initarg field-n
:initform n-value
:accessor field-n)))
Run Code Online (Sandbox Code Playgroud)
(这是否是好的设计是我将随着时间学习的东西)
我试图用宏来解决这个问题所以我可以打电话,说:
(defclass-with-accessors 'class-name
(('field-1 some-value)
('field-2 another-value)
(...)
('field-n n-value)))
Run Code Online (Sandbox Code Playgroud)
我的第一个解决方法(暂时忽略卫生)是分成两个宏:一个用于制作每个字段,另一个用于制作类本身.
使访问者字段的宏似乎是正确的:
(defmacro make-accessor-field (name form)
`(,name
:initarg ,(make-keyword name)
:initform ,form
:accessor ,name))
Run Code Online (Sandbox Code Playgroud)
但我没有得到主要的宏观权利.我的第一次尝试是:
(defmacro defclass-with-accessors (name body)
`(defclass ,name () \(
,(loop for my-slot in body collect
(make-accessor-field (car my-slot) (cadr my-slot)))))
Run Code Online (Sandbox Code Playgroud)
但这是无效的,SBCL在defmacro评估中给出了以下错误:
; in: DEFMACRO DEFCLASS-WITH-ACCESSORS
; (MAKE-ACCESSOR-FIELD (CAR MY-SLOT) …Run Code Online (Sandbox Code Playgroud)