2

私は Lisp プログラムを書いていて、型について少し気をつけようとしています。パフォーマンスが向上したと思いますが、ドキュメントと安全のために型注釈を使用することにもっと興味があります。問題はnil. これまでに2つの問題に遭遇しました。

展示物A:

>(defmethod foo ((bar bar-class) (quux quux-class))
   ...)

>(foo (make-instance 'bar-class) nil)
 ERROR: No applicable method, etcetera etcetera, because nil is not of type quux-class

展示物 B:

(defmethod initialize-instance :after ((f foo) &rest args)
  "Initialize the grid to be the right size, based on the height and width of the foo."
  (declare (ignorable args))
  (setf (slot-value f 'grid) (make-array (list (width f) (height f))
                                         :element-type 'foo-component
                                         :adjustable nil
                                         :initial-element nil)))

style-warning: 
  NIL is not a FOO-COMPONENT.

ここでのベストプラクティスは何ですか? これまでのところ、私が持っていたリモートで洞察力のある唯一のアイデアは、null オブジェクト パターン(defclass nil-quux-class (quux-class) ...)を使用してandを持つ(defclass nil-foo-component (foo-component) ...)ことですが、それはせいぜいハッキーに思えます。理由はわかりませんが、そうです。率直に言って、私はCLOSでパターン化された回避策を設計することに慣れていません:)

4

2 に答える 2

4

a への element-typeMAKE-ARRAYは、実際の型宣言ではないことに注意してください。これは、配列が格納できるデータの種類を Lisp 実装に与えるヒントです。次に、特殊な配列の実装を選択するかどうかを選択できます。

UPGRADED-ARRAY-ELEMENT-TYPEtypespec で示される型の項目を保持できる、最も特化した配列表現の要素型を返します。

CL-USER 12 > (upgraded-array-element-type '(integer 0 100))
(UNSIGNED-BYTE 8)

上記は、0 から 100 までの整数要素を持つ配列を要求することを意味します。この Lisp (ここでは LispWorks) は、要素 type の配列を提供します(unsigned-byte 8)

その他の例:

CL-USER 13 > (upgraded-array-element-type 'fixnum)
(SIGNED-BYTE 64)

CL-USER 14 > (upgraded-array-element-type 'complex)
T

CL-USER 15 > (defclass foo-component () ())
#<STANDARD-CLASS FOO-COMPONENT 402030196B>

CL-USER 16 > (upgraded-array-element-type 'foo-component)
T

Tこれは、配列が実際にすべての種類のデータ オブジェクトを格納することを意味します。

CL-USER 17 > (upgraded-array-element-type '(or null foo-component))
T

CL-USER 20 > (make-array 2
                         :element-type 'foo-component
                         :initial-element (make-instance 'foo-component))
#(#<FOO-COMPONENT 40203B9A03> #<FOO-COMPONENT 40203B9A03>)

CL-USER 21 > (array-element-type *)
T

上記は、Lisp も最初に要求されたものを忘れていることを示しています。実際に element-type の配列を取得し、Tその element-type を尋ねると、それはT.

于 2013-07-05T17:28:41.170 に答える