16

C コード内には、配列とその中の検索に使用されるゼロから始まるインデックスがあります。次に例を示します。

char * names[] = {"Apple", "Banana", "Carrot"};
char * name = names[index];

index埋め込まれた Lua スクリプトから、関数経由でアクセスできgetIndex()、配列ルックアップを複製したいと考えています。Luaの1ベースの配列を考えると、これを行うための「最良の」方法について合意されたものはありますか?

たとえば、C 配列と同じ内容の Lua 配列を作成することもできますが、インデックスを作成するときに 1 を追加する必要があります。

names = {"Apple", "Banana", "Carrot"}
name = names[getIndex() + 1]

または、より複雑なテーブルを使用して 1 を追加する必要を回避することもできますが、これは次のようなものを壊します#names

names = {[0] = "Apple", "Banana", "Carrot"}
name = names[getIndex()]

どのようなアプローチが推奨されますか?

編集:これまでの回答ありがとうございます。残念ながら、getIndex 関数内のインデックスに 1 を追加するソリューションは、常に適用できるとは限りません。これは、インデックスが「よく知られている」場合があるためです。つまり、インデックス 0 は「Apple」などを意味することが文書化されている場合があります。そのような状況では、上記の解決策のいずれかを優先する必要がありますか、それともより良い代替手段がありますか?

編集 2:回答とコメントに感謝します。この問題について考えるのに本当に役立ちました。問題が発生する 2 つの異なるシナリオがあり、理想的な解決策はそれぞれ異なる可能性があることに気付きました。

最初のケースでは、たとえば、時々異なる可能性のある配列と、現在の配列に対して単純に相対的なインデックスを考えてみましょう。インデックスは、コードの外では意味を持ちません。Doug Currie と RBerteig は完全に正しいです。配列は 1 ベースで、.getIndexを含む必要があり+1ます。前述したように、これにより、C 側と Lua 側の両方のコードを慣用的にすることができます。

2 番目のケースには、意味を持つインデックスと、おそらく常に同じ配列が含まれます。極端な例は where namescontains"Zero", "One", "Two"です。この場合、各インデックスの期待値はよく知られているので、Lua 側のインデックスを 1 ベースにするのは直感的ではないように感じます。他のアプローチのいずれかを優先する必要があると思います。

4

7 に答える 7

16

1 ベースの Lua テーブルを使用し+ 1、関数内に埋め込みgetIndexます。

于 2013-04-23T21:53:33.317 に答える
4

C配列を1ベースの配列に変えてみませんか?

char * names[] = {NULL, "Apple", "Banana", "Carrot"};
char * name = names[index];

率直に言って、これは C 側でいくつかの非直感的なコードにつながりますが、両方の側で機能する「既知の」インデックスが必要であると主張する場合、これが最良の選択肢のようです。

もちろん、よりクリーンな解決策は、これらの「よく知られている」インデックスをインターフェイスの一部にしないことです。たとえば、単純な数字の代わりに名前付き識別子を使用できます。Enum は C 側でこれにうまくマッチしますが、Lua では文字列をテーブル キーとして使用することもできます。

もう 1 つの可能性は、インターフェイスの背後にあるテーブルをカプセル化して、ユーザーが配列に直接アクセスするのではなく、C 関数呼び出しを介してのみアクセスできるようにすることです。これにより、任意の複雑なインデックス変換を実行できます。次に、その C 関数を Lua で公開するだけで、クリーンで保守可能なソリューションが得られます。

于 2013-04-30T15:19:14.200 に答える
3

C 配列をユーザーデータとして Lua に提示してみませんか? この手法は、PiL のセクション 'Userdata' のコードで説明されています。__index、、__newindexおよびメタ可能なメソッドを設定できます__len。また、クラスから継承して、他のシーケンス操作関数を通常のメソッドとして提供できます (たとえば、、、関数を使用して配列をarray.remove定義しarray.sortarray.pairsさらに微調整することでオブジェクト メソッドとして定義できます__index) 。 . このようにすることで、Lua と C の間に「同期」の問題がなくなり、「配列」テーブルが通常のテーブルとして扱われてオフバイワン エラーが発生するリスクを回避できます。

于 2013-05-02T06:43:17.463 に答える