сопрограммы kotlin: возможно без стандартной библиотеки? - PullRequest
5 голосов
/ 04 октября 2019

Мой вопрос довольно теоретический. Я совсем новичок в kotlin (только прошел обучение, не написал никакого реального кода).

Прочитав ссылку на язык, я запутался в том, что «suspend» - это ключевое слово, но я не могуне найти ничего похожего на «запуск» в списке ключевых слов. Это заставляет меня думать, что существует некоторая асимметрия: «suspend» - это функция компилятора, а «launch» - это функция библиотеки. Правильно ли мое понимание? Если так - разве не было бы лучше реализовать обе функции библиотеки или обе функции компилятора?

Я всегда думал, что вы всегда можете написать свою собственную стандартную библиотеку, используя доступные функции языка, но я все еще могуне вижу, действительно ли это применимо к этому случаю.

TL; DR: Могу ли я запустить сопрограмму, используя чистый kotlin, без импорта каких-либо библиотек (какими бы уродливыми это ни были)?

Ответы [ 3 ]

3 голосов
/ 04 октября 2019

Могу ли я запустить сопрограмму, используя чистый котлин, без импорта каких-либо библиотек (какими бы уродливыми это ни были)?

Нет. Все генераторы сопрограмм находятся в библиотеке kotlinx.coroutines, так что вам понадобится как минимум это. Теперь, очень теоретически, вы можете переопределить эту функцию самостоятельно. Но, вероятно, вы не должны.

Как это можно сделать, слишком долго для ответа StackOverflow, но попробуйте вызвать метод этого класса Kotlin из Java:

class AsyncWorks {
    suspend fun print() {
        println("Hello")
    }
}

Вы увидите, что, хотя метод Kotlin имеетбез аргументов, в Java это требует Continuation<? super Unit>. Это то, что делает ключевое слово suspend. Он добавляет Continuation<T> в качестве последнего аргумента нашей функции.

не лучше ли было бы реализовать обе функции библиотеки или обе функции компилятора?

В идеале вы бы хотели, чтобы все было "библиотечной функцией""так как легче развиваться. Удалить ключевое слово из языка очень сложно. Теоретически, можно использовать suspend в качестве ключевого слова. Quasar , будучи фреймворком, вместо этого использует аннотации. Язык программирования Go, с другой стороны, предполагает, что все функции приостановлены. Все эти подходы имеют свои преимущества и недостатки.
Котлин решил быть прагматичным и добавил ключевое слово suspend, оставив решение за разработчиками. Если вам интересна эта тема, я настоятельно рекомендую этот доклад Романа Елизарова, автора котлинских сопрограмм, который объясняет их решения: https://www.youtube.com/watch?v=Mj5P47F6nJg

2 голосов
/ 04 октября 2019

Маркер suspend добавляет скрытый параметр продолжения к сигнатуре функции и полностью изменяет байт-код реализации. Точки приостановки не сводятся к вызовам вспомогательных функций, они превращают ваш линейный программный код в конечный автомат, состояние которого сохраняется в объекте продолжения. Полученный байт-код даже не может быть представлен как программный код Java.

В отличие от этого, launch - это просто обычный библиотечный код, основанный на примитиве приостановки / возобновления.

1 голос
/ 04 октября 2019

Поскольку сопрограммы действительны для случаев использования, которые не поддерживают launch . Потому что suspend требует определенной специальной поддержки от компилятора , а launch не , если у вас уже есть suspend. Поскольку структурированный параллелизм представляет собой библиотечную инфраструктуру поверх языковой функции, а launch является частью этой конкретной инфраструктуры, которая делает особый выбор поверх того, что требует язык.

Запуск сопрограммы без каких-либо библиотек можно выполнить с помощью startCoroutine. kotlin.coroutines является частью Kotlin, а не библиотеки.

...