オブジェクトの初期化を行う - lisp-cookbook-ja/common-lisp GitHub Wiki

オブジェクトシステム(CLOS)

オブジェクトの初期化を行う

defclass で定義する際に初期値を設定することが可能です。 初期値の指定には、:initform、:initarg、:default-initargs等を状況に応じて使い分けます。

:initform で指定した値はインスタンスが作成された時や、クラスを変更して新しく追加されたスロットの初期値となります。

:initargは make-instance でのインスタンス作成時に指定するキーワードを指定します。

:default-initargs は、インスタンス作成時にキーワードでの初期値設定が省略された場合のデフォルト値をplist形式で設定します。

(defclass foo ()
  ((x :initform 0)
   (y :initform 10
      :initarg :y)
   (z :initarg :z))
  (:default-initargs :z 100))

(describe (make-instance 'foo))
;-> #<FOO 20095F07> is a FOO
;   X      0
;   Y      10
;   Z      100

;; キーワードにより初期値を与える。
;; (xスロットは:initargを設定していないため、この方法では初期値を設定できない)
(describe (make-instance 'foo :y 20 :z 30))
;-> #<FOO 232B438B> is a FOO
;   X      0
;   Y      20
;   Z      30

(defclass bar ()
  ((x :initform 1)
   (y :initform 2)
   (z :initform 3)
   (a :initarg :a))
  (:default-initargs :a 4))

(describe (change-class (make-instance 'foo) 'bar))

;-> #<BAR 232FA22B> is a BAR
;   X      0
;   Y      10
;   Z      100
;   A      #<unbound slot>

また、オブジェクトの生成はmake-instanceメソッドで行いますが、make-instanceメソッドは、初期化のために initialize-instance を呼び出しますのでカスタマイズしたい場合には、initialize-instanceに:afterメソッドを追加することが一般的に行なわれています。

関連

インスタンス作成時にあるスロットの値を元に他のスロットの値を初期化したい