سؤال

ما هو الفرق بين Coroutine واستمرار ومولد؟

هل كانت مفيدة؟

المحلول

سأبدأ بالمولدات، والرؤية لأنها أبسط القضية. نظرا لأن ZVolkov المذكورة، فهي وظائف / كائنات يمكن استدعاؤها بشكل متكرر دون إرجاعها، ولكن عند إبداء الإرجاع (العائد) قيمة ثم تعليق إعدامها. عندما يتم استدعاؤهم مرة أخرى، سيبدأون من مكانهم في الإعدام المعلقين ويقومون بأشياءهم مرة أخرى.

مولد هو في الأساس خفض Coloutine (غير المتماثلة). الفرق بين Coroutine والمولد هو أن Coroutine يمكن أن يقبل الحجج بعد أن تم استدعاؤه في البداية، في حين لا يمكن للمولد.

من الصعب بعض الشيء التوصل إلى مثال تافهة حيث كنت تستخدم Coroutines، ولكن هنا جرب أفضل ما لدي. خذ هذا (يتكون) رمز بيثون كمثال.

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

مثال على حيث يتم استخدام Coroutines هو Lexers ومحافل. بدون coloutines في اللغة أو المحاكاة بطريقة أو بأخرى، يجب خلط رمز Lexing and Parsing معا معا على الرغم من أنهم بالفعل شواغل منفصلة. ولكن باستخدام Coroutine، يمكنك فصل رمز Lexing وتحليل التعليمات البرمجية.

(سأقوم بالفرشاة على الفرق بين الجمود المتماثل وغير المتماثل. يكفي أن أقول إنهم ما يعادلهم، يمكنك التحويل من واحدة إلى أخرى، وغير المتماثلة للورود - وهي الأكثر مثل المولدات - هي أسهل لفهم. كنت أحدد كيف يمكن للمرء أن ينفذ الجمود غير المتماثلة في بيثون.)

المستمرات هي في الواقع وحوش بسيطة جدا. كل ما هم، هم وظائف تمثل نقطة أخرى في البرنامج، إذا اتصلت به، فسيتسبب في التنفيذ للتحول تلقائيا إلى النقطة التي تمثل الوظيفة التي تمثلها الوظيفة. يمكنك استخدام إصدارات مقيدة للغاية منهم كل يوم دون تحقيق ذلك حتى. الاستثناءات، على سبيل المثال، يمكن اعتبارها كنوع من الاستمرار من الداخل. سأقدم لك مثال python القائم على الاستمرار على استمرار.

قل بايثون وظيفة تسمى callcc(), ، استغرقت هذه الوظيفة حجما، أول وظيفة، والثاني قائمة من الحجج للاتصال بها. سيكون القيود الوحيد في هذه الوظيفة أن الحجة الأخيرة ستستغرق ستكون وظيفة (التي ستكون استمرارنا الحالي).

def foo(x, y, cc):
   cc(max(x, y))

biggest = callcc(foo, [23, 42])
print biggest

ماذا سيحدث هو ذلك callcc() سوف بدوره الدعوة foo() مع استمرار الحالي (cc)، أي إشارة إلى النقطة في البرنامج الذي callcc() كان يسمى. متي foo() يدعو إلى استمرار الحالي، إنه أمر أساسي في الأساس callcc() للعودة إلى القيمة التي تسمونها في الاستمرار الحالي مع، وعندما تفعل ذلك، فإنه يدفع المكدس إلى حيث تم إنشاء استمرار الحالي، أي عندما اتصلت callcc().

نتيجة كل هذا سيكون أن لدينا pytiant python الفرضية سوف تطبع '42'.

آمل أن يساعد ذلك، وأنا متأكد من أنه يمكن تحسين شرحي قليلا!

نصائح أخرى

تعد Coroutine واحدة من عدة إجراءات تتنقل من القيام بعملها، ثم توقف عن السيطرة على Coloutines الأخرى في المجموعة.

الاستمرار هو "مؤشر إلى وظيفة" تنتقل إلى بعض الإجراءات، ليتم تنفيذها ("استمر مع") عند القيام بذلك الإجراء.

مولد (في .NET) هو بناء لغة يمكن أن يبصق قيمة، "إيقاف مؤقت" التنفيذ للطريقة ثم تابع من نفس النقطة عند طلب القيمة التالية.

في إصدار أحدث من Python، يمكنك إرسال قيم إلى مولدات generator.send(), ، مما يجعل مولدات بيثون جوردو فعليا.

الفرق الرئيسي بين مولد بيثون، وغيرها من المولدات، يقول فنجر، هو أنه في بيثون، الخاص بك yield value يمكن العودة فقط إلى المتصل. بينما في غرينط، target.switch(value) يمكن أن يأخذك إلى هدف هدف محدد ويمنح قيمة target سوف تستمر في الجري.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top