回答:
ジェネレーターから始めて、ジェネレーターが最も単純なケースであることを確認します。@zvolkovが述べたように、これらは戻ることなく繰り返し呼び出すことができる関数/オブジェクトですが、呼び出されると値を返し(yield)、実行を一時停止します。再度呼び出されると、最後に実行を一時停止したところから起動し、再び処理を行います。
ジェネレーターは、本質的には削減された(非対称の)コルーチンです。コルーチンとジェネレーターの違いは、コルーチンは最初に呼び出された後に引数を受け入れることができるのに対し、ジェネレーターは受け取れないことです。
コルーチンをどこで使用するかという簡単な例を思いつくのは少し難しいですが、これが私の最善の試みです。例として、この(作成された)Pythonコードを取り上げます。
def my_coroutine_body(*args):
while True:
# Do some funky stuff
*args = yield value_im_returning
# Do some more funky stuff
my_coro = make_coroutine(my_coroutine_body)
x = 0
while True:
# The coroutine does some funky stuff to x, and returns a new value.
x = my_coro(x)
print x
コルーチンが使用される例は、レクサーとパーサーです。言語にコルーチンがないか、何らかの形でエミュレートされていない場合、字句解析と解析コードは、実際には2つの別々の問題であるにもかかわらず、一緒に混合する必要があります。ただし、コルーチンを使用すると、字句解析と解析コードを分離できます。
(対称コルーチンと非対称コルーチンの違いをブラッシングします。それらが同等であると言えば十分です。一方からもう一方に変換できます。非対称コルーチン(ジェネレーターに最も似ています)が理解しやすくなりました。Pythonで非対称コルーチンを実装する方法を概説していました。)
継続は実際には非常に単純な獣です。それらはすべて、プログラム内の別のポイントを表す関数であり、これを呼び出すと、実行は関数が表すポイントに自動的に切り替わります。あなたはそれを実現することさえせずに、それらの非常に制限されたバージョンを毎日使用しています。たとえば、例外は一種の裏返しの継続と考えることができます。継続のPythonベースの疑似コードの例を紹介します。
たとえば、Pythonにはという関数がcallcc()
あり、この関数は2つの引数を取った。1つ目は関数であり、2つ目はそれを呼び出すための引数のリストである。その関数の唯一の制限は、関数が取る最後の引数が関数になることです(これが現在の継続になります)。
def foo(x, y, cc):
cc(max(x, y))
biggest = callcc(foo, [23, 42])
print biggest
何が起こるだろうことはつまりcallcc()
ターンコールの場合とfoo()
現在の継続と(cc
、これでプログラムのポイントへの参照です)、callcc()
と呼ばれていました。foo()
現在の継続を呼び出す場合、それは基本的に、callcc()
現在の継続を呼び出している値で戻るように指示することと同じであり、それを行うと、スタックが現在の継続が作成された場所、つまり、callcc()
。
これらすべての結果として、架空のPythonバリアントが出力されます'42'
。
それがお役に立てば幸いです。私の説明はかなり改善されると思います。
コルーチンは、グループ内の他のコルーチンに制御を与えるために順番に仕事をしてから一時停止するいくつかの手順の1つです。
継続とは、あるプロシージャに渡される「関数へのポインタ」であり、そのプロシージャが完了したときに実行されます(「継続」)。
ジェネレータ(.NET内)は、値を吐き出し、メソッドの実行を「一時停止」し、次の値を要求されたときに同じポイントから続行できる言語構造です。
新しいバージョンのPythonでは、を使用してジェネレータに値を送信できますgenerator.send()
。これにより、Pythonジェネレータが効果的にコルーチンになります。
pythonジェネレーターと他のジェネレーター(greenletなど)の主な違いは、pythonではyield value
呼び出し側にしか戻れないことです。Greenletを使用している間target.switch(value)
、特定のターゲットコルーチンに移動し、target
が引き続き実行される値を生成できます。
yield
呼び出しが「ジェネレータ」と呼ばれる同じ関数内になければなりません。あなたがすることはできませんyield
Pythonの者が呼ばれている理由は、サブ機能、から半コルーチン Luaは持っていながら、非対称コルーチンを。(収量を