use*_*837 4 lisp common-lisp clos
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))
Run Code Online (Sandbox Code Playgroud)
但当我尝试:
(defclass a () ((x my-option 123)))
Run Code Online (Sandbox Code Playgroud)
SBCL编译错误:
初始化参数无效:调用类时的MY-OPTION
Run Code Online (Sandbox Code Playgroud)SB-MOP:STANDARD-DIRECT-SLOT-DEFINITION>.
[SB-PCL型的条件:: INITARG-ERROR]
所以问题.如何在插槽定义中添加其他属性(如"my-option")?
实现可以做到这一点.但是用户无法添加随机属性.如果Common Lisp实现支持元对象协议,可以通过自定义Metaclass添加它.但这意味着还需要提供计算插槽等的方法.
那是先进的Lisp." 元对象协议的艺术"在第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))
Run Code Online (Sandbox Code Playgroud)
让我们在用户定义的类中使用它:
(defclass foo ()
((a :initarg :a :foo :bar))
(:metaclass foo-meta-class))
Run Code Online (Sandbox Code Playgroud)
然后,插槽定义对象将具有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
Run Code Online (Sandbox Code Playgroud)
如果财产有任何实际意义,显然还有更多.
归档时间: |
|
查看次数: |
652 次 |
最近记录: |