#kotlin
#kotlin
Вопрос:
Следующие два метода содержат одинаковую функциональность, единственное отличие состоит в том, что один приостанавливаемый, а другой нет (то же самое для параметров).
Как я могу извлечь реализацию и повторно использовать ее для обеих функций?
fun validationWrapper(supplier: () -> Unit) = try {
supplier.invoke()
} catch (ex: Exception) {
when (ex) {
is IllegalArgumentException, is IllegalStateException -> throw ValidationException(ex.message!!)
else -> throw ex
}
}
suspend fun validationWrapper(supplier: suspend () -> Unit) = try {
supplier.invoke()
} catch (ex: Exception) {
when (ex) {
is IllegalArgumentException, is IllegalStateException -> throw ValidationException(ex.message!!)
else -> throw ex
}
}
Я мог бы сохранить только приостанавливаемую функцию, но это означало бы, что я должен использовать a runBlocking
каждый раз, когда я ее использую.
Ответ №1:
Сохраните версию без приостановки и создайте ее inline
. Это решает проблему, поскольку встроенный лямбда-выражение может содержать приостанавливающие вызовы, не будучи объявленным suspend
само по себе. Именно так это делает большинство стандартных библиотек Kotlin ( forEach
, map
, и т.д.):
inline fun validationWrapper(supplier: () -> Unit) = try {
supplier.invoke()
} catch (ex: Exception) {
when (ex) {
is IllegalArgumentException, is IllegalStateException -> throw ValidationException(ex.message!!)
else -> throw ex
}
}
Кроме того, это обычно полезно для функций более высокого порядка, которые принимают лямбда-выражения для объявления inline
, поскольку это позволяет избежать дополнительных затрат на экземпляры лямбда.