9

さまざまな要素のHTMLを出力するためのメソッドをいくつか作成しています。各メソッドの出力は同じですが、必ずしも同じ入力が必要なわけではありません。

ニーズをエコーする方法も同様game-boardに取る必要がありplayerます(各プレイヤーは自分のピースしか見ることができないため)

(defmethod echo ((board game-board) (p player)) ... )

ボードスペースをエコーする場合、プレーヤーごとに変更する必要はありません(ディスパッチは実際にはgame-boardメソッドで行われ、後でechoスペースを呼び出します)。理想的には、私はできるだろう

(defmethod echo ((space board-space)) ... )
(defmethod echo ((space empty-space)) ... )

後で、自分自身を正しく表示するために、プレーヤーだけでなく、それ以上のことを知る必要があるオブジェクトに遭遇することも考えられます。ただし、同じジェネリックに特化したメソッドがすでに存在するため、エラーが発生します。

The generic function #<STANDARD-GENERIC-FUNCTION ECHO (4)> takes 2 required arguments;

echo-space戻ってこれらのメソッドに名前を付けるのは理想的ではないようecho-boardです。

特殊なオブジェクトに基づいて他の引数を変更する標準的な方法はありますか?私は次のようなことをする必要があります

(defgeneric echo (thing &key player ...) ...)

また

(defgeneric echo (thing &rest other-args) ...)

?より一般的には、誰かが私に具体的にまともなチュートリアルを教えてもらえdefgenericますか?(関連するPCLの章といくつかのCLOSチュートリアルを読みましたが、ここで質問している状況については説明していません)。

4

3 に答える 3

5

一般的に言えば、2つの関数のインターフェースがあまりにも異なる場合は、それらが実際には同じ操作の専門分野ではなく、同じ名前であってはならないことを示します。オプション/キー引数のみに特化したい場合、それを実現する方法は、ジェネリック関数を呼び出し、特殊化する欠落した引数のデフォルト値を提供する通常の関数を使用することです。

キーンの本は、CLOSの最も包括的なガイドだと私は信じています。残念ながら、それは本の形でしか入手できないようです。

于 2012-02-20T06:03:51.447 に答える
3

メソッドが同じパラメーターを取り、データ型のみが異なる場合はいつでも簡単です。しかし、ジェネリック関数とメソッドがすべて同じ名前を使用しているが(もちろん)ラムダリストが大幅に異なる場合、私は個人的に&optionalパラメーターを使用するのではなく、&keyパラメーターを使用して意図を明示する傾向があります。後で読みやすくなると思います。

次のようなものを試してください(すでにクラスaとクラスbがあるふりをします):

(defgeneric foo (object &key &allow-other-keys)
  (:documentation "The generic function. Here is where the docstring is defined."))

(defmethod foo ((object class-a) &key &allow-other-keys)
  (print "Code goes here. We dispatched based on type Class A."))

(defmethod foo ((object class-b) &key (x 1) (y 2) &allow-other-keys)
  (print "Code goes here. We dispatched based on type Class B. We have args X and Y."))

「メソッドの組み合わせ」が関係しているため、ディスパッチングロジックが使用するメソッドの可能な選択肢を「フロー」するためには、互換性のないラムダリスト(つまりパラメーターリスト)が壊れてしまうチェーンのようなメソッド定義を考える必要があります。そのチェーン。そのため、メソッド定義には、特に必要のない&keyキーと&allow-other-keyがあります。それらをDEFGENERICとメソッド定義に入れると、クラスbに基づいてディスパッチするメソッド定義を持つことができます。

免責事項:私はCommon Lispの初心者なので、これを一粒の塩と一緒に飲んでください!

于 2012-04-16T00:17:35.093 に答える
0

エコーする各オブジェクトが独自の(および継承された)スロットに必要なすべてのプロパティを持つように、オブジェクト/クラスを再構築するのはどうですか?

そうすれば、必要なものがすでにオブジェクトに格納されているため、オブジェクトでechoを呼び出すときに引数としてそれらを渡す必要はありません。

于 2012-02-21T00:23:11.123 に答える