Я новичок в Kotlin, и мне нужно реализовать код, который выполняет процедуру установления связи. Это означает, что есть входные и выходные данные и конечный автомат. Пример:
class Handshake {
fun readData(data: List<Byte>): Outcome {
if (currentState == State.STATE_1) {
if (inspectState1Data(data) == Result.INVALID) {
return Outcome.NEED_MORE_DATA //
} else {
currentState = State.STATE_2
return Outcome.CALL_AGAIN
}
} else if (currentState == State.STATE_2) {
when (inspectState2Data(data)) {
Result.REQUIRES_EXTRA_INFO -> return Outcome.PROVIDE_EXTRA_INFO
Result.INVALID -> return Outcome.FAILURE
}
}
}
}
Эту функцию readData()
придется вызывать повторно. Если возвращается Outcome.CALL_AGAIN
, он просто вызывается снова. Если возвращается Outcome.PROVIDE_EXTRA_INFO
, дополнительная информация должна быть передана классу рукопожатия сначала каким-то образом et c.
В этом примере функция короткая и легко читается, однако, как только задействованы другие состояния, и состояния становятся более сложными, этот код может быстро стать беспорядочным.
Я бы хотел изменить это на что-то вроде:
suspend fun processHandshake(): Boolean {
// State 1
while (true) {
// Loop until we get valid data
val data: List<Byte> = suspendUntilResumedWithData() // How would this look like in Kotlin?
if (inspectState1Data(data) != Result.INVALID)
break
}
// State 2
while (true) {
// Loop until we are done. If during the process we
// require extra info, request one. In this state,
// however, receiving invalid data is not recoverable,
// we need to exit with failure instead.
val data: List<Byte> = suspendUntilResumedWithData()
when (inspectState2Data(data)) {
Result.REQUIRES_EXTRA_INFO -> {
val extraInfo: ExtraInfo = suspendUntilResumedWithExtraInfo()
processExtraInfo(extraInfo)
}
Result.INVALID -> return false // Return false to indicate failure
}
}
return true // Success - return true
}
Для меня вторая форма более читабельна , и, конечно же, хорошо работает с инфраструктурой сопрограмм Kotlin, особенно с такими деталями, как отмена заданий и т. д. c. Этот код также имеет гораздо более последовательный вид по сравнению с другим.
Однако у меня нет четкого представления о том, как будут выглядеть suspendUntilResumedWithData()
и suspendUntilResumedWithExtraInfo()
. Я знаю об объектах Continuation, но не знаю, как их здесь правильно использовать. Есть предложения?