Как передать обобщенную лямбду приостановки в метод класса в Kotlin? - PullRequest
1 голос
/ 29 сентября 2019

Хотите иметь функцию внутри открытого класса, которая может принимать лямбду-приостановку и запускать ее.

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

class ChildClass : SuperClass() {

    // does work :)
    fun launch(block: suspend ChildClass.() -> Unit) =
        coroutineThing { this.block() }

}
open class SuperClass {

    // doesn't work :(
    fun <T : SuperClass> launch(block: suspend T.() -> Unit) = 
        coroutineThing { this.block() }

}

Я получаю ошибку: Expression 'block' of type 'suspend T.() -> Unit' cannot be invoked as a function. The function 'invoke()' is not found.

Редактировать:

В конечном итоге вызвать этот метод из экземпляраChildClass, как это: ChildClass().launch { doStuff() }

Ответы [ 2 ]

3 голосов
/ 29 сентября 2019

Вы можете написать так, но я не знаю, как это работает :) Для меня это выглядит как вопрос Kotlin.

open class SuperClass {
    fun <T : SuperClass> launch(block: suspend T.() -> Unit) =
        coroutineThing { block.invoke(this as T) }
}

, но в этом случае вы должны вызвать его так:

ChildClass().launch<ChildClass> { println("test") }

но вы можете немного изменить его, чтобы вызвать его так, как вы хотите:

open class SuperClass<T : SuperClass<T>> {
    fun launch(block: suspend T.() -> Unit) =
        coroutineThing { block.invoke(this as T) }
}

class ChildClass : SuperClass<ChildClass>()

//invokation
ChildClass().launch { println("test") }
0 голосов
/ 29 сентября 2019

Как насчет этого?

open class SuperClass {


    fun<T: SuperClass> launch(superClass: T, block: suspend T.() -> Unit) {
        GlobalScope.launch {
            superClass.block()
        }
    }

}


open class ChildClass: SuperClass() {
    suspend fun print() {

    }
}


fun test () {
    val a = ChildClass()
    a.apply {
        launch(this) {
            print()
        }
    }
}
...