Context receivers
В рабочем проекте попробовал добавленные недавно context receivers. Вкратце, это очередной сахар, который позволяет требовать, чтобы функция вызывалась в контексте, содержащем какой-то класс как this
:
context(Logger, DBConnection, Request)
fun someFunc() {
log(select(request.param))
}
Под капотом компилятор генерирует дополнительные параметры для вызова функции.
В текущей версии (1.6.21) все очень сыро — я споткнулся об пару багов компилятора и пару ошибок во время исполнения в довольно простых случаях. Для прода это точно не готово (я использовал в тестах). Могут получиться уродские лямбды:
suspend fun someFun(
block: suspend context(Logger, DBConnection) Request.(Param) -> Unit
)
Компилятор не всегда понимает, из какого контекста метод (и я натыкался на случаи, когда ему не удавалось это объяснить). Как и с suspend
, функции приобретают “цвет”. У this
непонятный тип — вроде объединение, но явно это не получить. Наконец, форматирование съезжает:) Больше критики можно почитать тут, похвалу — тут, а больше вариантов применения — тут.
Без сахара подобные задачи можно решать созданием одного класса Context
и вызова функций с дополнительным параметром(ами) или через receiver: fun Context.someFunc()
. Была бы поддержка типов-объединений, то тогда это было бы гораздо более читаемо (особенно с typealias
). Ну а так вообще это все ради того, чтобы неявно передавать аргумент в функцию. И подобную проблему уже давно решили с помощью имплиситов в Scala. В общем, мне кажется, что начинается излишнее переусложнение, которое еще и хреново реализовано.