Lisp 插槽定义的附加属性
说: 实现可以自由地将其他属性添加到 规范化插槽规范,前提是这些不是符号 可在公共lisp用户包中访问,或由任何包导出 在ANSI通用Lisp标准中定义 举个例子:Lisp 插槽定义的附加属性,lisp,common-lisp,clos,Lisp,Common Lisp,Clos,说: 实现可以自由地将其他属性添加到 规范化插槽规范,前提是这些不是符号 可在公共lisp用户包中访问,或由任何包导出 在ANSI通用Lisp标准中定义 举个例子: (defclass sst (plane) ((mach mag-step 2 locator sst-mach locator mach-location :reader mach-speed :reader mach))
(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]
所以问题来了。如何将其他属性(如“我的选项”)添加到插槽定义中?实现可以做到这一点。但是用户不能添加随机属性。如果公共Lisp实现支持元对象协议,则可以通过自定义元类添加它。但这意味着还需要提供计算插槽等的方法 这是高级Lisp。《元对象协议的艺术》(The Art of The Metaobject Protocol)一书在第3章中有一个例子,扩展了该语言 一个简单的示例(适用于LispWorks): 让我们在用户定义的类中使用它:
(defclass foo ()
((a :initarg :a :foo :bar))
(:metaclass foo-meta-class))
然后,插槽定义对象将有一个插槽foo
,其内容为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
CL-USER 10>(查找类“foo”)
#
CL-USER 11>(类直接插槽*)
(#)
CL-USER 12>(描述(第一*)
#是一个FOO-STANDARD-DIRECT-SLOT-DEFINITION
福:酒吧
读者零
作家零
说出一个
初始形式零
初始化函数NIL
T型
旗帜1
INITARGS(:A)
分配:实例
无槽文件
很明显,如果财产有任何实际意义的话,还有更多的内容。谢谢!此示例在lispworks中运行良好。但是对于SBCL和closer mop,它返回一个错误:“类被指定为类的超类,但是元类和不兼容。为SB-mop定义一个方法:VALIDATE-SUPERCLASS以避免此错误。[类型SIMPLE-error的条件]”,您只需要完全按照它的说明执行:
(defmethod VALIDATE SUPERCLASS((类foo元类)(超类标准类))t@user1312837:LispWorks仅当foo meta class
meta class不是标准类的子类时才需要validate superclass
。这很有意义。对于SBCL,只需添加Philipp提到的方法即可。@RainerJoswig有趣的是,至少在SBCL中这样做时,我可以获得di上的foo槽的值rect插槽定义,但是有效插槽定义上的foo值仍然为零。defclass表单似乎没有正确初始化有效插槽中的foo。在LispWorks personal 6.1.1中也确认了这一点。我必须搜索AMOP以寻找线索。
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