5

http://mop.lisp.se/concepts.html说:

一个实现可以自由地向规范化插槽规范添加其他属性,前提是这些属性不是在 common-lisp-user 包中可访问的符号,也不是由 ANSI Common Lisp 标准中定义的任何包导出的符号。

例如:

(defclass sst (plane)
     ((mach mag-step 2
            locator sst-mach
            locator mach-location
            :reader mach-speed
            :reader mach))
  (:metaclass faster-class)
  (another-option foo bar))

但是当我尝试时:

(defclass a () ((x my-option 123)))

SBCL 编译错误:

无效的初始化参数:类调用中的 MY-OPTION

                SB-MOP:STANDARD-DIRECT-SLOT-DEFINITION>.    

[SB-PCL::INITARG-ERROR 类型的条件]

所以这个问题。如何向插槽定义添加其他属性(如“我的选项”)?

4

1 回答 1

8

一个实现可以做到这一点。但是用户不能添加随机属性。如果 Common Lisp 实现支持元对象协议,可以通过自定义元类添加它。但这意味着还需要提供计算槽等的方法。

这就是高级 Lisp。本书The Art of the Metaobject Protocol在第 3 章“扩展语言”中有一个示例。

一个简单的例子(在 LispWorks 中工作):

(defclass foo-meta-class (standard-class) ())

(defclass foo-standard-direct-slot-definition (standard-direct-slot-definition)
  ((foo :initform nil :initarg :foo)))

(defclass foo-standard-effective-slot-definition (standard-effective-slot-definition)
  ((foo :initform nil :initarg :foo)))

(defmethod clos:direct-slot-definition-class ((class foo-meta-class) &rest initargs)
  (find-class 'foo-standard-direct-slot-definition))

(defmethod clos:effective-slot-definition-class ((class foo-meta-class) &rest initargs)
  (find-class 'foo-standard-effective-slot-definition))

让我们在用户定义的类中使用它:

(defclass foo ()
  ((a :initarg :a :foo :bar))
  (:metaclass foo-meta-class))

然后 slot-definition 对象将有一个foo带有 content的 slot bar

CL-USER 10 > (find-class 'foo)
#<FOO-META-CLASS FOO 42200995AB>

CL-USER 11 > (class-direct-slots *)
(#<FOO-STANDARD-DIRECT-SLOT-DEFINITION A 42200B4C7B>)

CL-USER 12 > (describe (first *))

#<FOO-STANDARD-DIRECT-SLOT-DEFINITION A 42200B4C7B> is a FOO-STANDARD-DIRECT-SLOT-DEFINITION
FOO                     :BAR
READERS                 NIL
WRITERS                 NIL
NAME                    A
INITFORM                NIL
INITFUNCTION            NIL
TYPE                    T
FLAGS                   1
INITARGS                (:A)
ALLOCATION              :INSTANCE
DOCUMENTATION-SLOT      NIL

如果该属性应该具有任何实际意义,显然还有更多内容。

于 2014-02-24T12:46:31.493 回答