¿Es posible crear un tipo de function recursiva en Kotlin?
Tengo funciones que representan pasos en un process. Cada function también conoce el siguiente paso, si hay uno. Me gustaría poder hacer algo como:
fun fooStep() : Step? { ... do something ... return ::barStep // the next step is barStep }
Estas funciones se llaman desde una function central de despacho, que contiene un código como este:
- ¿Cómo se obtiene un Idlingresource para trabajar en Kotlin con corutinas?
- Aplicación; había usado un AppComponent diferente; durante la verificación previa
- La propiedad en la interfaz no puede tener un campo de respaldo
- Haga una nueva list de otras dos lists de diferentes types comparando los valores de cada tipo
- Android Kotlin: envía notifications cada minuto
var step = startStep while (step != null) { step = step() }
Tenga en count que la lógica en un paso particular también determina el siguiente paso, si es que hay uno.
Pensé que podría definir Step
como:
typealias Step = () -> Step?
Entonces un Step
es una function que devuelve otro Step
o nulo. Sin embargo, esto no se puede comstackr con:
Kotlin: Recursive type alias in expansion: Step
Puedo evitar esto envolviendo la function en un object. p.ej:
data class StepWrapper(val step: () -> StepWrapper?)
y cambiando mis firmas de funciones en consecuencia.
Desafortunadamente, esto significa que no puedo usar ::barStep
funciones (por ej .: ::barStep
), sino que tengo que envolverlas en un StepWrapper
:
fun fooStep() : StepWrapper? { ... do something ... return StepWrapper(::barStep) }
(También tengo que cambiar mi ciclo de envío, en consecuencia).
Me gustaría evitar la necesidad de crear estos objects de envoltura, si es posible. ¿Hay alguna manera de hacer esto en Kotlin?
- ¿Por qué puedo insert un código de línea antes de DayForecast (HashMap (it)) en Kotlin?
- Procesamiento de annotations con el estudio Android Kapt
- La function en línea no puede acceder a API no pública: @PublishedApi vs @Suppress vs @JvmSynthetic
- Cómo apuntar JVM 9 en Kotlin con Gradle?
- Kotlin + MVP: anulación accidental
- Kotlin: ¿Hay alguna manera de limpiar las sobrecargas de numbers?
- ¿Por qué algunos files de Kotlin muestran el ícono de candado?
- Almacenar datos en BEAN (Spring Boot REST)
Puede definirlo utilizando una interfaz genérica:
interface StepW<out T> : ()->T? interface Step : StepW<Step> class Step1 : Step { override fun invoke(): Step? = Step2() } class Step2 : Step { override fun invoke(): Step? = null }
Donde Step
es su tipo de function recursiva.
Así es cómo puedes hacer que funcione, aunque realmente no estoy seguro de lo que intentas lograr con él:
typealias Fun<T> = () -> T typealias Step<T> = () -> (T) typealias Step1 = Step<Fun<Step2>> typealias Step2 = Step<Fun<Step3>> typealias Step3 = Step<Unit> fun step1(): Step1 { return { println("step 1") ::step2 } } fun step2(): Step2 { return { println("step 2") ::step3 } } fun step3(): Step3 { return { println("done") } }
Use un Enum para implementar el patrón de estado con estados finitos y prefiera devolver valores que no sean nulos. Una enumeración puede henetworkingar de una function.
enum class Step : () -> Step { Step1 { override fun invoke() = Step2 }, Step2 { override fun invoke() = End }, End { override fun invoke() = this } } fun work() { var step = Step.Step1 while (step !== Step.End) { step = step() } }
- kapt no resuelve las classs generadas por protobuf
- Deshabilitar la compilation incremental para kapt