0

Common Lisp の特別な変数だけがアンバインドできると言われています。すべてのレキシカル変数のデフォルト値はnil. クラススロットはクロージャーのようなものに存在すると思っていましたが、明らかに存在しません。

パラメータなしで CLOS スロットを定義し:initform(いずれにせよバインドされることを期待してnil)、インスタンスの作成時に値を指定しないと、バインドされていないスロットを持つインスタンスが取得されます。なぜそうなのですか?便利ではありません。

4

2 に答える 2

8

これは、オンデマンドでスロット値を計算する場合など、値が nil になる場合がある場合に非常に便利です。バインドされていないスロットにアクセスする場合、CLOS は通常SLOT-UNBOUND、エラーを通知するジェネリック関数を呼び出します。ただし、エラーの代わりに、必要SLOT-UNBOUNDに応じて値を計算して保存するように特化できます。後続のアクセスではスロット値が直接使用され、 を使用してスロットの「キャッシュ」をフラッシュできますSLOT-MAKUNBOUND

何らかのセンチネルの「バインドされていない」値を使用してこれを行うことができますが、代わりに機能を組み込むと非常に便利です。

使用例slot-unbound:

(defclass foo ()
  ((bar :accessor bar)
   (baz :accessor baz)))

(defmethod slot-unbound (class (instance foo) slot-name)
  (declare (ignorable class))
  (setf (slot-value instance slot-name) nil))

実際に:

CL-USER> (defparameter *foo* (make-instance 'foo))
*FOO*
CL-USER> (bar *foo*)
NIL
CL-USER> (setf (baz *foo*) (not (baz *foo*)))
T
于 2014-06-24T12:45:36.967 に答える
5

CLOS インスタンスはクロージャーではありません

CLOS インスタンスは通常、クロージャーとして実装されません。それは難しいでしょう。それらは、スロットのベクトルのようなものを持つデータ構造です。Common Lisp の構造に似ています。CLOS インスタンスと構造体の違いにより複雑になります。CLOS インスタンスは実行時にスロットの数を変更することができ、実行時に CLOS インスタンスのクラスを変更することができます。

スロットにNIL値があることを確認する

一部の高度な CLOS を使用すると、スロットに NIL 値があることを確認できます。この例のパッケージの関数は、CLOSCL の別のパッケージにある可能性があることに注意してください。

この関数は、インスタンスのすべてのスロットを調べます。スロットがバインドされていない場合は、 に設定されNILます。

(defun set-all-unbound-slots (instance &optional (value nil))
  (let ((class (class-of instance)))
    (clos:finalize-inheritance class)
    (loop for slot in (clos:class-slots class)
          for name = (clos:slot-definition-name slot)
          unless (slot-boundp instance name)
          do (setf (slot-value instance name) value))
    instance))

ミックスインクラスを作成します。

(defclass set-unbound-slots-mixin () ())

修正は、オブジェクトの初期化後に実行されます。

(defmethod initialize-instance :after ((i set-unbound-slots-mixin) &rest initargs)
  (set-all-unbound-slots i nil))

(defclass c1 (set-unbound-slots-mixin)
  ((a :initform 'something)
   b
   c))


CL-USER 1 > (describe (make-instance 'c1))

#<C1 4020092AEB> is a C1
A      SOMETHING
B      NIL
C      NIL
于 2014-06-22T08:47:42.417 に答える