6

必要なことがわかっているいくつかのプロパティと、基本構造には必要のない任意の数のその他のプロパティを含む構造を定義しようとしています。

(defstruct (node (:type list)) label [other args here])

私はあなたができる機能で知っています:

(defun foo (arg1 &rest args) ...)

&restに相当するものはありdefstructますか?

私はちょうど Lisp を学んでいるので、何かが足りない気がします。同等のものがない場合&rest、これについてどうすればよいかについてのアイデアはありますか? 前もって感謝します!

4

3 に答える 3

6

あなたが探しているものは正確には明らかではありません。構造体のデフォルトのケースは、固定数のスロットを持つレコード タイプで、それぞれに名前があり、defstructマクロによって生成された関数を介してアクセスできます。たとえば、完了したら

(defstruct node 
  label)

nodeのラベルにアクセスしてnode-label高速なルックアップ時間を得ることができます (通常はメモリ チャンクへの単なるインデックスであるため)。ここで、あなたがやっているように、リストを構造体の実装として使用することを選択できます。この場合、はornode-labelの単なるエイリアスです。carfirst

(defstruct (node (:type list))
  label)

CL-USER> (make-node :label 'some-label)
(SOME-LABEL)
CL-USER> (node-label (make-node :label 'some-label))
SOME-LABEL
CL-USER> (first (make-node :label 'some-label))
SOME-LABEL
CL-USER> (car (make-node :label 'some-label))

任意のリストベースのキーと値のペアを探している場合は、Common Lisp にいくつかの便利な関数が含まれているプロパティ listが必要になるでしょう。

プロパティ リストも含む構造体が必要な場合は、そのリストに値を設定する特別なコンストラクターを追加できます。例えば、

(defstruct (node (:type list)
                 (:constructor make-node (label &rest plist)))
  label
  plist)

CL-USER> (make-node 'some-label :one 1 :two 2)
(SOME-LABEL (:ONE 1 :TWO 2))
CL-USER> (node-plist (make-node 'some-label :one 1 :two 2))
(:ONE 1 :TWO 2)
于 2013-07-09T18:15:59.467 に答える
2

これはコメントではなく別の返信の価値があると思ったので、ここに行きます:

構造体やオブジェクトが必要だと思っていても、これらのエンティティが満たさない特別な要件がある場合、実際に必要なのは別のデータ構造である可能性があります。オブジェクトまたは構造体は、いくつかの条件が満たされている場合に適しています。そのような条件の 1 つは、スロットが静的に認識されていることです。これにより、コンパイラはコードについてより適切に判断できるようになり、最適化とエラー報告の両方に適しています。

一方、データ構造もあります。言語標準ライブラリで提供されるものもあれば、その上に追加されるものもあります。それらの多くを提供する 1 つのライブラリを次に示します: http://cliki.net/cl-containersですが、特別な場合にはさらに多くのライブラリがあります。

ここで、オブジェクトや構造体を拡張してスロットを動的に追加できるようにするよりも、リスト、配列、ある種のツリーなどの構造体を使用する方がよいと主張します。これは、通常、スロットにアクセスする時間が無視できると予想されるためです。つまり、O(1) であることが期待されます。これは、オブジェクトが持つスロットの数に関係なく、通常発生することです。さて、下にあるリストを使用しているときは、同じセマンティクスを維持しながら、それを O(n) にしています! もちろん、ハッシュテーブルを使用して O(1) にすることもできます (ただし、これは一般的にスロットアクセスよりも遅くなります) が、nilスロットが存在しない場合に返されるなど、他の予期しない動作が発生します。通常のエラーなどの代わりに

このような方法でオブジェクトを拡張することは、CL では一般的な方法ではないと思います。これがおそらく、他の応答がそうするのを思いとどまらせない理由です。私は他の回答者に比べて CL のことをよく知りませんが、他の言語でのこの種の操作にはかなりの悲しみを感じてきました。

于 2013-07-10T06:15:39.330 に答える