2

私はCプログラムに埋め込むためにLuaで小さなCLIモジュールを書いています。

末尾呼び出しループのどちらかを選択して、プロンプトを処理するための最良のアプローチは何であるか疑問に思いました。

末尾呼び出しとして、私は次のようなことをします:

call = { help=function () print 'just ask politely' end }

function shell ()
  io.write ('% ')
  local cmd = io.read ()

  if cmd ~= 'quit' then      
    call[cmd] () -- for simplicity assume call[cmd] is never nil
    return shell ()
  end
end

私は次の質問をします:

  1. 末尾呼び出しの除去の正しい使用/実装ですか?末尾呼び出しの除去call[cmd] ()を利用しないように、スタックに障害が発生しますか?

  2. 次のようなループを使用する方が良いですか?はいの場合、なぜですか?

    repeat
      io.write ('% ')
      local cmd = io.read()
    
      -- do stuff
    until cmd == 'quit'
    
  3. Luaでのプログラミングでは

    末尾呼び出しは、呼び出しに扮した後藤です。

    では、末尾呼び出しとループの間に具体的な違いはありますか?

ありがとうございました。

4

1 に答える 1

10

テールコール除去の正しい使用/実装ですか?

shell最後の への呼び出しが Lua 構文による適切な末尾呼び出しであるかどうかを尋ねている場合、答えは yesです。

call[cmd] () は、テールコールの除去を利用しないように、スタックに障害をもたらしますか?

関数呼び出しは、あなたが考えている方法でスタックを変更しません。Lua では、テール コールの唯一return Function(params)の要件は、関数からの戻り値以外の余分な戻り値がない形式であることです。

適切な末尾呼び出しは、自分自身を呼び出す必要さえありません。再帰的である必要はありません。

次のようなループを使用する方が良いですか? はいの場合、なぜですか?

それは主観的な点です。個人的には、何が起こっているのかについてループの方が明確だと思います。

ただし、パフォーマンスの客観的な質問が必要な場合は、これを考慮してください。テール コールはループよりも高速になることはありません。パフォーマンスの点で得られる絶対的なベストは同等です。

そして、おそらくそうではないでしょう。Lua テール コールの「最適化」とは、単に現在の関数のスタック エントリを再利用することを意味します。Lua はグローバル テーブルから関数を取得する必要があります。Lua は関数呼び出しのオーバーヘッドをすべて処理する必要があります。より多くのスタック メモリを割り当てる必要がないだけです。

スタックをオーバーフローさせず、不要なときにメモリを割り当てないことが重要です。

テールコールとループの間に具体的な違いはありますか?

上記を参照。

于 2012-07-20T20:16:07.890 に答える