11

Lua unpack 関数で奇妙な動作に遭遇しました

table1 = {true, nil, true, false, nil, true, nil}
table2 = {true, false, nil, false, nil, true, nil}

a1,b1,c1,d1,e1,f1,g1 = unpack( table1 )
print ("table1:",a1,b1,c1,d1,e1,f1,g1)

a2,b2,c2,d2,e2,f2,g2 = unpack( table2 )
print ("table2:",a2,b2,c2,d2,e2,f2,g2)

出力:

table1: true    nil true    false   nil nil nil
table2: true    false   nil nil nil nil nil

2 番目のアンパックは、最初の nil 値までのパラメーターを提供します。私はそれで暮らすことができました。最初のテーブルは 4 を提供しますか? 真ん中が nil のパラメータ。nil ではない 4 つのパラメーターがありますが、表示されているものではありません。

誰でもこれを説明できますか?これは codepad.org と lua 5.1 で試しました

4

2 に答える 2

17

この問題は、開始インデックスと終了インデックスを指定して終了インデックスとしてunpack()使用するだけで解決できます。table.maxn()

table1 = {true、nil、true、false、nil、true、nil}

a1,b1,c1,d1,e1,f1,g1 = unpack( table1, 1, table.maxn(table1) )
印刷 ("table1:",a1,b1,c1,d1,e1,f1,g1)
-->table1: true nil true false nil true nil

2 つのテーブルの処理方法が一致しない本当の理由は、テーブルの配列部分の長さを決定するロジックにあります。

このluaB_unpack()関数は、テーブルの呼び出しluaL_getn()に関して定義されている which を使用します。は配列の最後の位置を調べ、それがテーブル内の境界のバイナリ検索を実行します (「t[i] が nil ではなく、t[i+1] が nil になるように」)。配列の末尾の二分探索が、その後の処理が異なる理由です。lua_objlen()luaH_getn()luaH_getn()niltable1table2

これは、配列の最後のエントリが の場合にのみ問題になりますnil

From Programming in Lua (pg.16) (この本を購入する必要があります): 配列に穴 (内部に nil 要素) がある場合、長さ演算子はこれらの nil 要素のいずれかを終了マーカーとして想定する場合があります。したがって、ホールを含む可能性のある配列では長さ演算子を使用しないでください。

unpack()長さ演算子を使用していlua_objlen()ます。これは、配列の「[the] nil要素のいずれかを最後と見なす可能性があります」。

于 2009-11-04T23:18:02.193 に答える
3

2.2 - 値と型

[...] 型テーブルは連想配列、つまり、数値だけでなく任意の値 (nil を除く) でインデックス付けできる配列を実装します。テーブルは異機種混合にすることができます。つまり、すべての型 (nil を除く) の値を含めることができます 。[...]

エントリに指定すると、テーブルの列挙nil壊れ、変数が適切に初期化されません。

問題のある動作を示す簡単な例を次に示します。

table1 = {true, false, nil, false, nil, true, nil}
for k,v in ipairs(table1) do
  print(k, v)
end

出力:

1   true
2   false
>Exit code: 0
于 2009-11-04T10:59:48.560 に答える