Intereting Posts
Как проверить, отсортирован ли массив строк в алфавитном порядке или нет с помощью Kotlin? Котлинский эквивалент «экспортного дефолта» в JavaScript Конструкция объявления Koltin Generic-site <a T> Корда: Сторона отклонила запрос сеанса, поскольку Провайдер не был зарегистрирован Реализация интерфейса kotlin в java Делегирование конструктора Котлина во внутренний класс данных? Как получить элементы из общего списка безопасным типом Как создать объект JavaScript для объекта Kotlin? Использование Gradle для создания банки с зависимостями с Kotlin-DSL Внешние аннотации Kotlin для JDK не заданы Список загрузки ConfigurationProperties из YML Процессор аннотации Kotlin дает ошибку времени компиляции при использовании Room with Android Studio 3.0 beta7 Может ли объект класса, созданный «на лету» в Котлине, иметь конструктор? Исключение OutOfMemory при использовании Kotlin :: class.java.canonicalName Kotlin 1.1.3-2 Невозможно создать экземпляр фрагмента в OnResume Android

Kotlin – альтернатива урожаю кортета Python и посылает

Что было бы идиоматической альтернативой Kotlin для следующего фрагмента скрипта 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 

Поэтому мне нужно получить значения из сопрограммы (через канал?), Но также отправить значения обратно в сопрограмму. Нужно ли мне для этого два канала?

Solutions Collecting From Web of "Kotlin – альтернатива урожаю кортета Python и посылает"

Двухкоординатные генераторы, которые присутствуют в Python и ES6, на самом деле не являются идиоматическими в Котлине, потому что Котлин является статически типизированным языком, и поэтому двухсторонние генераторы весьма неудобны в использовании. Просто взгляните на g.send(None) в приведенном выше коде, чтобы понять, почему это так. Таким образом, реализация двухсторонних генераторов не предоставляется в стандартной библиотеке Kotlin или в поддерживающих библиотеках.

Однако поддержка сопрограмм на языке Kotlin достаточно универсальна, и при необходимости могут быть реализованы двухсторонние генераторы, чтобы вести себя так же, как в Python и ES6. Соответствующая реализация доступна здесь и занимает всего несколько десятков строк кода.

С приведенной выше реализацией двухканального генератора ваш код Python может быть непосредственно переведен в Kotlin по очереди:

 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 } 

Этот код работает так же хорошо, как и его версия Python, однако он не является идиоматическим по множеству причин. Во-первых, поддержка сопрограмм в Котлине позволяет определять произвольные функции приостановки и, таким образом, позволяет выражать подобное поведение безопасным образом, не прибегая к произвольному маркеру начала или не используя строки для обозначения операций. Вы можете прямо определить объект, у которого есть inc и mult как его первоклассные приостанавливающие операции, или, по крайней мере, изменить реализацию, так что необязательный запуск вызова не требуется. Вы можете изучить сопроводительный документ coroutines, в котором объясняются все примитивы низкого уровня, которые предоставляет Kotlin, и есть ряд примеров, которые помогут вам начать работу.