動機:
構造物は比較的低レベルの施設です。「スピード」は重要な設計目標でした。ライター関数を介した間接参照は、標準ではサポートされていません(私が読んだように)。現在、構造の効率を高める必要がない限り、デフォルトとしてCLOSを使用してください(構造を使用したスロットの読み取りと書き込みを高速化できる場合があります)。
最初のスタイル:
INTERNは使用せず、FIND-SYMBOLを使用してください。パッケージも指定します。指定しない場合、FIND-SYMBOLは*package*のランタイム値をパッケージとして使用します。
2番目-DEFSTRUCT
ANSI CL規格を正しく読んだ場合、DEFSTRUCTがDEFCLASSのようにスロットのライター関数を作成するわけではありません。
CL-USER 24 > (defstruct foo bar baz)
FOO
CL-USER 25 > #'(setf foo-bar)
Error: Undefined function (SETF FOO-BAR) in form (FUNCTION (SETF FOO-BAR)).
したがって、DEFSTRUCTで定義されたそのような関数がないため、そのような名前(SETF FOO-BAR)を作成し、その関数を見つけようとすると失敗します。
ユーザーコード(setf(foo-bar some-struct)42)で機能するものは、DEFSTRUCTによって提供される定義済みのSETF拡張に基づいていますが、定義済みのSETFアクセサー関数には基づいていません。
一部のCommonLisp実装は、ANSICLの非標準拡張としてライター関数を提供する場合があります。
考えられる解決策:
a)CLOSクラスを使用すると、DEFCLASSは必要な処理を実行します
b)ライター関数を自分で作成する
(defun (setf foo-bar) (new-value struct)
(setf (foo-bar struct) new-value))
今:
(funcall (fdefinition '(setf foo-bar)) 300 *foo*)
上記はその後動作します。
c)(SETF SLOT-VALUE)-一部の実装のもう1つの非標準機能。
Common Lispの一部の実装では、これはCLOSクラスだけでなく、構造体でも機能します。
(setf (slot-value some-struct 'bar) 42)
Allegro CLがそれをサポートしているかどうかはわかりませんが、それは簡単にわかります。