2010-09-01 39 views
4

在我的类定义中,我想根据另一个插槽的值初始化一个插槽。这里是诸如此类的事情,我想这样做:基于Common Lisp对象系统类定义中的其他插槽值初始化插槽

(defclass my-class() 
    ((slot-1 :accessor my-class-slot-1 :initarg slot-1) 
    (slot-2 :accessor my-class-slot-2 :initform (list slot-1)))) 

然而,这并不编译:

1 compiler notes: 

Unknown location: 
    warning: 
    This variable is undefined: 
     SLOT-1 

    warning: 
    undefined variable: SLOT-1 
    ==> 
     (CONS UC-2::SLOT-1 NIL) 


Compilation failed. 

有没有办法做到这一点?

回答

3

使用initialize-instance :after记录here

+0

这是可以使用结构的东西吗? – mck 2015-11-18 01:20:48

2

这是道格·柯里的回答扩展:

(defclass my-class() 
    ((slot-1 :accessor my-class-slot-1 :initarg :slot-1) 
    (slot-2 :accessor my-class-slot-2))) 

(defmethod initialize-instance :after 
      ((c my-class) &rest args) 
    (setf (my-class-slot-2 c) 
     (list (my-class-slot-1 c)))) 

这里显示出它的工作原理电话:

> (my-class-slot-2 (make-instance 'my-class :slot-1 "Bob")) 
("Bob") 

详情请参阅this article

+0

Zach Beane也在comp.lang.lisp上给出了这个答案(或者几乎是这样),但是在输入自己的代码之前我没有注意到它。谢谢扎克和道格! – 2010-09-01 17:40:50

2
(defparameter *self-ref* nil) 


(defclass self-ref() 
() 

    (:documentation " 
Note that *SELF-REF* is not visible to code in :DEFAULT-INITARGS.")) 


(defmethod initialize-instance :around ((self-ref self-ref) &key) 
    (let ((*self-ref* self-ref)) 
    (when (next-method-p) 
     (call-next-method)))) 



(defclass my-class (self-ref) 
    ((slot-1 :accessor slot-1-of :initarg :slot-1) 
    (slot-2 :accessor slot-2-of 
      :initform (slot-1-of *self-ref*)))) 




CL-USER> (let ((it (make-instance 'my-class :slot-1 42))) 
      (values (slot-1-of it) 
        (slot-2-of it))) 
42 
42 
CL-USER>