2012-11-16 31 views
6

引数をlua_resumeとlua_yieldに渡す目的は何ですか?Lua:lua_resumeとlua_yieldの引数の目的

私はlua_resumeへの最初の呼び出しで、引数が再開されているlua関数に渡されることを理解します。意味あり。しかし、私はlua_resumeへのその後のすべての呼び出しがコルーチン関数の引数を「更新」することを期待しています。しかし、そうではありません。

lua_yieldが返す引数をlua_resumeに渡す目的は何ですか?コルーチンの下で実行されているlua関数は、lua_resumeによって渡された引数にアクセスできますか?

答えて

10

Nicolが言ったこと。あなたはまだあなたがしたい場合は最初のresume呼び出しからの値を保持することができます。

do 
    local firstcall 
    function willyield(a) 
    firstcall = a 
    while a do 
     print(a, firstcall) 
     a = coroutine.yield() 
    end 
    end 
end 

local coro = coroutine.create(willyield) 
coroutine.resume(coro, 1) 
coroutine.resume(coro, 10) 
coroutine.resume(coro, 100) 
coroutine.resume(coro) 

1 1 
10 1 
100 1 
+0

私はこれが質問に答えないように感じる。OPは、標準ライブラリ 'coroutine.resume()'とは異なるセマンティクスを持つ/ C API /関数lua_resume()とlua_yield()に関するものでした(例えば、lua_resumeは3つの引数をとります.2つはlua_State ...) – BadZen

+0

私はそれがパラメータを渡す目的についての質問に答えると思うし、Luaインタプリタを持ってみるのは簡単な例です。実際、OPはニコルの答えの下で彼のコメントで多くを言った。 あなたが良いと思ったら、いつでも自分の答えを出すことができます。 –

+0

libsのcoroutineオブジェクト(例えば、lua_Stateをカプセル化する)とC APIを使用する場合には大きな違いがあります。私はより良い答えがないので、C APIについて具体的に質問する別の質問を開きました。 Nicholの答えとここでは、どちらもcoroutineライブラリオブジェクトについて説明しています。 lua_ * APIに関してこれを実装するコードは約100行あります。それは明白ではなく、ドキュメンテーションの詳細は不明です。 – BadZen

5

ルアは魔法のようにオリジナルの引数に新しい値を与えることはできません。それらは、最適化に応じて、もはやスタックにないかもしれません。さらに、コードが生成されたときにそのコードがどこにあったかが示されていないため、それらの引数をもう見ることができなくなる可能性があります。たとえば、コルーチンが関数を呼び出した場合、その新しい関数は古い関数に渡された引数を見ることができません。

coroutine.yield()は、コルーチンを継続するresumeコールに渡された引数を返します。これにより、yieldコールのサイトで必要なパラメータを処理できるようになります。それは、再開を行うコードが、特定のコードと通信して降伏することを可能にする。 yield()はその引数をresumeの戻り値として渡し、resumeはその引数を戻り値としてyieldに渡します。これはコミュニケーションの経路を設定します。

他の方法ではできません。確かに、yieldサイトから見えないかもしれない引数を変更することではありません。シンプルでエレガントで、理にかなっています。

また、誰かの価値観を突き止めるのは非常に失礼だと考えられています。特に動作中の機能。覚えておいてください:引数は値で満たされたローカル変数です。ユーザーは、変数自体が変更されない限り、変数の内容が変更されることを期待しないでください。結局のところ、変数はlocalです。それらはローカルでしか変更できません。したがって、名前。

+0

感謝を印刷します!したがって、一旦コルーチンが開始されると、ローカル値は外部的に変更することはできません。私はグローバル変数によってコルーチンの内部と通信する必要があると思いますか? たとえば、コルーチンは距離内にいくつのオブジェクトがあるかを知る必要があるゲーム内で「近くのオブジェクト」の数を持つことがあります。これを行うには、近くのオブジェクトの数を格納するためにグローバルを持たなければならないだろうか?名前空間をグローバルで保護するのを避けるため、私が再開する直前にコルーチンに値することを期待していました。 – RandyGaul

+0

値は変更できます。 coroutine.yield()コールの結果を、元のパラメータと同じ変数に代入するだけで済みます。例えば私の答えを見てください。 –

+0

@RandyGaul: "*一度コルーチンを起動すると、ローカル値を外部的に変更することはできません。*"ローカル変数は外部から変更することはできません。コルーチンは特別ではありません。この番号を渡したい場合は、それらをパラメータとして 'resume'に渡し、' yield'からの戻り値としてそれらを収集します。私が述べたように、それはあなたが持っている通信インターフェイスです。 –

関連する問題