5

Lua でのプログラミングのセクション 4.1から。

複数の割り当てでは、Lua は最初にすべての値を評価してから、割り当てを実行します。したがって、次のように、複数代入を使用して 2 つの値を交換できます。

x, y = y, x -- x' fory'を入れ替える

割り当ては実際にどのように機能しますか?

4

1 に答える 1

10

複数の割り当てがどのように実装されるかは、使用している Lua の実装によって異なります。実装は、セマンティクスを維持する限り、好きなことを自由に行うことができます。つまり、実装方法に関係なく、Lua の本で説明されているように、すべての値を LHS に割り当てる前に RHS に保存した場合と同じ結果が得られるはずです。


実際の実装にまだ興味がある場合、できることの 1 つは、特定のプログラム用に生成されるバイトコードを確認することです。たとえば、次のプログラムを取ると

local x,y = 10, 11
x,y = y,x

luac -lLua 5.2のバイトコード コンパイラ ( ) に渡すと、

main <lop.lua:0,0> (6 instructions at 0x9b36b50)
0+ params, 3 slots, 1 upvalue, 2 locals, 2 constants, 0 functions
    1   [1] LOADK       0 -1    ; 10
    2   [1] LOADK       1 -2    ; 11
    3   [2] MOVE        2 1
    4   [2] MOVE        1 0
    5   [2] MOVE        0 2
    6   [2] RETURN      0 1

MOVE オペコードは、右レジスタの値を左レジスタに割り当てます (詳細については、Lua ソースの lopcodes.h を参照してください)。どうやら、何が起こっているかというと、レジスタ 0 と 1 が使用されてxおりy、スロット 2 が一時的な追加スロットとして使用されているようです。x最初の 2 つのオペコードで定数を使用しyて初期化され、次の 3 つのオペコードでは、手動で行うのと同じように、「一時的な」2 番目のスロットを使用してスワップが実行されます。

tmp = y -- MOVE 2 1
y = x   -- MOVE 1 0
x = tmp -- MOVE 0 2

スワッピング代入と静的初期化を行う際にLuaがどのように異なるアプローチを使用したかを考えると、異なる種類の複数の代入に対して異なる結果が得られたとしても驚かないでしょう(テーブルフィールドの設定はおそらく非常に異なって見えるでしょう。メタメソッドのために順序が重要になるはずです...)。ただし、バイトコードが出力されるソース内の部分を 100% 確実に見つける必要があります。前に述べたように、特に LuaJIT と PUC Lua を比較すると、これらすべてが Lua のバージョンと実装によって異なる可能性があります。

于 2013-03-06T20:00:53.113 に答える