Koroutin ile devam ve üretici arasındaki fark nedir?
Koroutin ile devam ve üretici arasındaki fark nedir?
Yanıtlar:
Jeneratörlerle başlayacağım, en basit durum olduklarını görüyorum. @Zvolkov'un belirttiği gibi, bunlar geri dönmeden tekrar tekrar çağrılabilen işlevler / nesnelerdir, ancak çağrıldığında bir değer döndürür (verim) ve ardından yürütmelerini askıya alırlar. Tekrar çağrıldıklarında, yürütmeyi en son askıya aldıkları yerden başlayacaklar ve işlerini tekrar yapacaklardır.
Bir jeneratör aslında bir kısaltılmış (asimetrik) koroutindir. Bir yardımcı program ve üretici arasındaki fark, bir yardımcı programın başlangıçta çağrıldıktan sonra argümanları kabul edebilmesidir, ancak bir üretici bunu yapamaz.
Coroutines'i nerede kullanacağınıza dair önemsiz bir örnek bulmak biraz zor, ama işte en iyi denemem. Bu (yapılmış) Python kodunu örnek olarak alalım.
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
Koroutinlerin kullanıldığı yerlere örnek olarak sözlükler ve ayrıştırıcılar verilebilir. Dilde eşgüdüm olmadan veya bir şekilde taklit edilmeden, kodlama ve ayrıştırma kodu gerçekten iki ayrı endişe olsa da birlikte karıştırılmalıdır. Ancak bir program kullanarak, lexing ve ayrıştırma kodunu ayırabilirsiniz.
(Simetrik ve asimetrik koroutinler arasındaki farkı inceleyeceğim. Eşdeğer olduklarını söylemek için yeterli, birinden diğerine dönüştürebilirsin ve asimetrik koroutinler - en çok benzeyen jeneratörler - Birinin Python'da asimetrik koroutinleri nasıl uygulayabileceğinin altını çiziyordum.)
Devamlar aslında oldukça basit hayvanlardır. Tüm bunlar, programda başka bir noktayı temsil eden işlevlerdir, bu da onu çağırırsanız, yürütmenin otomatik olarak işlevin temsil ettiği noktaya geçmesine neden olur. Farkına bile varmadan her gün çok kısıtlı sürümlerini kullanıyorsunuz. Örneğin istisnalar, bir çeşit içten dışa devam olarak düşünülebilir. Size bir Python tabanlı sahte kod örneği vereceğim.
Diyelim ki Python adlı bir işleve sahipti callcc()
ve bu işlev birincisi bir işlev, ikincisi de onu çağırmak için bir argüman listesi olan iki argüman aldı. Bu işlev üzerindeki tek kısıtlama, aldığı son argümanın bir işlev (şu anki devamımız olacak) olacağıdır.
def foo(x, y, cc):
cc(max(x, y))
biggest = callcc(foo, [23, 42])
print biggest
Ne olur yani callcc()
aramayı açacak foo()
akım devamında (ile cc
) olduğunu, programda noktasında bir başvuru hangi callcc()
denirdi. Ne zaman foo()
geçerli devamını çağırır, aslında söylemekle aynı olduğunu callcc()
size mevcut devamı aradığınız değeri ile dönmek ve bu yapmasından, geçerli devamı oluşturulduğu yerde, yani beni aradığında geri yığını rulolar callcc()
.
Tüm bunların sonucu, varsayımsal Python varyantımızın basması olacaktır '42'
.
Umarım bu yardımcı olur ve açıklamamın biraz geliştirilebileceğinden eminim!
Koroutin, sırayla işlerini yapan ve daha sonra gruptaki diğer koroutinlere kontrol vermek için duraklayan birkaç prosedürden biridir.
Devam, bu prosedür tamamlandığında yürütülecek ("ile devam") bazı prosedürlere ilettiğiniz bir "işleve işaretçi" dir.
Jeneratör (.NET'te), bir değer verebilir, yöntemin yürütülmesini "duraklatabilir" ve bir sonraki değer istendiğinde aynı noktadan devam edebilen bir dil yapısıdır.
Python'un yeni sürümünde, generator.send()
python Generators'ı etkin bir şekilde eşgüdümlü kılan Jeneratörlere değerler gönderebilirsiniz .
Python Jeneratör ve diğer jeneratör, örneğin greenlet arasındaki temel fark, python'da yield value
sadece arayan kişiye geri dönebileceğinizdir. Greenlet'deyken, target.switch(value)
sizi belirli bir hedef koroutine götürebilir ve target
çalışmaya devam edeceği bir değer verebilir.
yield
çağrılar "Jeneratör" adı verilen aynı fonksiyonda olmalıdır. Yapamazsınız yield
Python en denir nedenle bir alt fonksiyonu, gelen yarı coroutines Lua sahipken, asimetrik coroutines . (Verimleri yaymak için öneriler var, ama bence bu sadece suları çamurlu.)