2

関数のような構造体のスロットの 1 つを定義し、そのスロットにアクセスして関数を使用することは可能ですか? ある場合、どのように使用できますか?たとえば、次のようなものです。

(defstruct problem
   state
   (player (defun getplayer (some-state) (findplayer 1 some-state))) 
   (points (defun getpoints (some-state someplayer) (findpoints someplayer some-state)))
 )
4

3 に答える 3

2

あなたが書いたものは機能しませんが、これを行うことができます:

(defstruct problem () state)
(defgeneric getplayer (problem)
  (:method ((p problem))
    (find-player 1 (problem-state p))))
(defgeneric getpoints (problem player)
  (:method ((p problem) player)
    (findpoints player (problem-state p))))
于 2013-11-11T19:18:32.050 に答える
2

次の 2 つの手法のいずれかを使用します。

1 つ目は、関数をスロットに格納する代わりに、関数に名前を付けるシンボルを格納することです。これは、構造体 def 自体の外で、名前付き関数が別の場所で定義されていることを前提としていることに注意してください。

(Defstruct problem
  State
 (Points 'getpoints)
 (Player 'getplayer))

これは、次のような方法で使用できます。

 (Defvar p (make-problem ...))
 (Funcall (problem-points p) x)
 (Funcall (problem-player p) x y)

これが機能する理由は、シンボルが提供されると、Funcall が呼び出し前にその fdefinition を自動的に解決するためです。2 番目のアプローチは非常に似ていますが、名前付き関数を表すシンボルの代わりに、スロットを無名関数 (「ラムダ式」と呼ばれる) に直接設定します。このアプローチは、リストした例とさらに類似しています。スロット値に割り当てられた関数は、構造の定義またはインスタンス化内で定義されており、その関数が他の場所で定義されていることに依存していません。そう:

(Defstruct problem
  State
 (Points (lambda (arg0) (some-computation arg0)))
 (Player (lambda (arg0 arg1) (other-computation arg0 arg1))))

その後:

 (Defvar q (make-problem ...))
 (Funcall (problem-points q) x)
 (Funcall (problem-player q) x y)

それが役に立てば幸いです!

于 2013-11-13T00:20:42.080 に答える