Pregunta

¿Cuál es la diferencia entre una co-rutina y una continuación y un generador?

¿Fue útil?

Solución

Voy a empezar con los generadores, ya que ellos son el caso más simple. Como @zvolkov mencionado, son funciones / objetos que se pueden llamar varias veces sin volver, pero cuando recibe la llamada de retorno (rendimiento) de un valor y luego suspender su ejecución. Cuando se les llama de nuevo, van a empezar desde donde se agoten suspenden la ejecución y hacer sus cosas de nuevo.

Un generador es esencialmente un corte hacia abajo corrutina (asimétrica). La diferencia entre una co-rutina y el generador es que una co-rutina puede aceptar los argumentos después de que se le ha llamado inicialmente, mientras que un generador no puede.

Es un poco difícil llegar a un ejemplo trivial de donde debería usar co-rutinas, pero aquí es mi mejor intento. Tomar esto (compuesta) de código Python como un ejemplo.

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

Un ejemplo de donde se utilizan corrutinas es lexers y analizadores. Sin co-rutinas en el idioma o emulado de alguna manera, léxico y código de análisis tiene que ser mezclados entre sí a pesar de que en realidad son dos preocupaciones separadas. Pero el uso de una co-rutina, se puede separar el código léxico y análisis sintáctico.

(Voy a pincel sobre la diferencia entre corrutinas simétricas y asimétricas Baste decir que son equivalentes, se puede convertir de uno a otro, y corrutinas asimétricos -. Que son los más, como generators- -son más fácil de entender. yo estaba delineando cómo se podría implementar co-rutinas asimétricos en Python.)

Las continuaciones son en realidad animales muy simples. Todo lo que son, son funciones que representan otro punto del programa que, si se llama a ella, hará que la ejecución para cambiar automáticamente hasta el punto que representa la función. Utiliza versiones muy restringido de ellos todos los días sin siquiera darse cuenta. Excepciones, por ejemplo, se pueden considerar como una especie de continuación de dentro a fuera. Te voy a dar un ejemplo basado en Python pseudocódigo de una continuación.

Say pitón tenía una función llamada callcc(), y esta función se llevó dos argumentos, el primero es una función, y el segundo es una lista de argumentos para llamar con. La única restricción en esa función sería que el último argumento que se necesita será una función (que será nuestra continuidad actual).

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

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

¿Qué pasaría es que callcc() a su vez foo() llamada con la continuación actual (cc), es decir, una referencia al punto del programa al que se llama callcc(). Cuando foo() llama la continuación actual, que es esencialmente el mismo que decirle callcc() para volver con el valor que está llamando la continuación actual con, y cuando se hace eso, se deshace la pila para el que se creó la continuación actual, es decir, cuando que llamó callcc().

El resultado de todo esto sería que nuestra hipotética variante Python imprimiría '42'.

Espero que ayude, y estoy seguro de que mi explicación se puede mejorar en un poco!

Otros consejos

Coroutine es uno de los diversos procedimientos que se turnan haciendo su trabajo y luego hacer una pausa para darle el control a los otros co-rutinas en el grupo.

La continuación es un "puntero a una función" se pasa a algún procedimiento, a ser ejecutado ( "continuó con") cuando se lleva a cabo este procedimiento.

Generador (en .NET) es una construcción del lenguaje que puede escupir un valor, "pausa" ejecución del método y luego proceder desde el mismo punto cuando se les pregunta por el valor siguiente.

En la versión más reciente de Python, puede enviar los valores a generadores con generator.send(), lo que hace Generadores pitón corrutinas eficaz.

La principal diferencia entre el generador pitón, y otro generador, greenlet decir, es que en Python, su yield value sólo puede volver de nuevo a la persona que llama. Mientras que en greenlet, target.switch(value) te puede llevar a un corrutina objetivo específico y producir un valor en el que el target continuaría para funcionar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top