Alternativa de Kotlin al performance de la corotina de Python y enviar

¿Cuál sería una alternativa idiomática de Kotlin al siguiente fragment de coronet de python?

def generator(): c = 1 while True: op = yield c if op == 'inc': c += 1 elif op == 'mult': c *= 2 # main g = generator() a = g.send(None) # start b = g.send('inc') c = g.send('mult') d = g.send('inc') print([a, b, c, d]) # 1, 2, 4, 5 

Entonces necesito get valores de la coroutine (¿a través de un canal?), Pero también enviar los valores nuevamente a la corutina. ¿Necesito dos canales para eso?

    Los generadores bidireccionales del tipo que están presentes en Python y en ES6 no son realmente idiomáticos en Kotlin, porque Kotlin es un lenguaje estáticamente tipado y, por lo tanto, los generadores de dos vías son bastante torpes de usar. Simplemente eche un vistazo a g.send(None) en el código anterior para comprender por qué es así. Por lo tanto, la implementación de generadores de dos vías no se proporciona en la biblioteca estándar de Kotlin ni en las bibliotecas de soporte.

    Sin embargo, el soporte de corutinas en lenguaje Kotlin es lo suficientemente genérico y se pueden implementar generadores de dos vías, si es necesario, para comportarse como en Python y ES6. La implementación correspondiente está disponible aquí y toma solo unas pocas docenas de líneas de código.

    Con la implementación anterior del generador bidireccional, su código Python se puede traducir directamente a Kotlin línea por línea:

     fun generator() = generate<Int, String> { var c = 1 while (true) { val op = yield(c) when (op) { "inc" -> c += 1 "mult" -> c *= 2 } } } fun main(args: Array<String>) { val g = generator() val a = g.next("") // start val b = g.next("inc") val c = g.next("mult") val d = g.next("inc") println("$a $b $c $d") // 1, 2, 4, 5 } 

    Este código funciona tan bien como su versión de Python, sin embargo no es idiomático por multitud de razones. Por un lado, es que el soporte de corutinas en Kotlin permite la definición de funciones de suspensión arbitrarias y, por lo tanto, hace posible express un comportamiento similar de una manera segura sin recurrir a un marcador de inicio arbitrario ni usar cadenas para denotar operaciones. Puede definir directamente un object que tenga inc y mult como sus operaciones de suspensión de primera class, o, al less, cambie la implementación de modo que no se necesite una invocación de inicio ficticio. Le invitamos a estudiar el documento de layout coroutines que explica todas las primitivas de bajo nivel que ofrece Kotlin y tiene una serie de ejemplos para comenzar.