Intereting Posts
Как вводить представления фрагментов, используемых в PagerAdapter с кинжалом? Статус состояния Vault для UNONSUMED / CONSUMED ListView может отображаться в Activity, но не может отображаться в фрагменте Ошибка компиляции в Eclipse в проекте Kotlin + Java, но проект строится с Maven Статические аналогичные методы в Android-приложении с kotlin Как мы можем реализовать базовый адаптер с kotlin в android? Kotlin + Dagger2: не может быть предоставлен без конструктора @Inject или из метода @ Provides- или @ Produces-annotated Неправильная позиция PopupWindow внутри RecyclerView после notifyItemChanged Как бесконечно повторять последовательность в Котлине? kotlin.TypeCastException: null не может быть отброшен в ненулевой тип kotlin.Long как реализовать java-интерфейс SAM в Котлине? Предоставить Kotlin предупреждение о назначении гибкого / платформенного типа для непустого типа? Ошибка базы данных Kotlin CursorIndexOutOfBoundsException Как создать сопоставимый тип Kotlin? firebase db: модели с переданными свойствами Котлина

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, и есть ряд примеров, которые помогут вам начать работу.