У меня есть функции, которые представляют шаги в процессе. Каждая функция также знает следующий шаг, если он есть. Я хотел бы иметь возможность сделать что-то вроде:
fun fooStep() : Step? {
... do something ...
return ::barStep // the next step is barStep
}
Эти функции вызываются из центральной диспетчерской функции, которая содержит примерно такой код:
var step = startStep
while (step != null) {
step = step()
}
Обратите внимание, что логика конкретного шага также определяет следующий шаг, если он вообще есть.
Я думал, что могу определить Step
как:
typealias Step = () -> Step?
Таким образом, Step
— это функция, которая возвращает еще один Step
или ноль. Однако это не скомпилируется с:
Kotlin: Recursive type alias in expansion: Step
Я могу обойти это, обернув функцию в объект. например:
data class StepWrapper(val step: () -> StepWrapper?)
и соответствующим образом изменив сигнатуры моих функций.
К сожалению, это означает, что я не могу просто использовать функциональные литералы (например: ::barStep
), но вместо этого должен обернуть их в StepWrapper
:
fun fooStep() : StepWrapper? {
... do something ...
return StepWrapper(::barStep)
}
(Я также должен изменить свой цикл отправки соответственно.)
Я хотел бы избежать необходимости создавать эти объекты-оболочки, если это возможно. Есть ли способ сделать это в Котлине?
Map<Condition, Step>
по сравнению с подходомStepWrapper
, описанным в вопросе? - person Laurence Gonsalves   schedule 10.06.2017typealias
, учитывая, что он явно указывает на проблему рекурсивных типов. - person Laurence Gonsalves   schedule 10.06.2017data class Node(val step: () -> Unit, val nextNode: Node?) fun step1(): Unit { println("step 1") } fun step2(): Unit { println("step 2") } val node2 : Node = Node(::step2, null) val node1 : Node = Node(::step1, node2) var curNode: Node? = node1 while (curNode != null) { curNode.step.invoke() curNode = curNode.nextNode }
Если функция может условно вернуть более одного шага, то необходима карта. - person bartonstanley   schedule 12.06.2017