小编fsa*_*hes的帖子

在宏上使用循环在Common Lisp中生成类槽

在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)

macros loops common-lisp clos

3
推荐指数
1
解决办法
381
查看次数

标签 统计

clos ×1

common-lisp ×1

loops ×1

macros ×1