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
}
}
我只能保留可挂起的功能,但这意味着我runBlocking
每次使用它时都应该使用它。
解决方案
Keep the non-suspend version and make it inline
. This solves the problem because the inlined lambda can then contain suspending calls without being declared suspend
itself. It is how most of the Kotlin stdlib does this (forEach
, map
, etc.):
inline fun validationWrapper(supplier: () -> Unit) = try {
supplier.invoke()
} catch (ex: Exception) {
when (ex) {
is IllegalArgumentException, is IllegalStateException -> throw ValidationException(ex.message!!)
else -> throw ex
}
}
Also, it is generally useful for higher-order functions that take lambdas to be declared inline
, because it avoids extra costs of lambda instances.
推荐阅读
- arrays - 如何在二维数组的每个单元格中找到具有相同数值的行?
- angular - Angular - 如何使用 ngFor 在选择选项之间添加分隔符?
- google-sheets - 如何使用谷歌表格中最后填充的值自动填充列的空白单元格?
- authentication - 如何使用 django rest 框架对应用程序而不是用户进行身份验证?
- arrays - 如何将表转换为 Json 数组?
- javascript - 错误:无法在 Tizen TV 上开始调试
- python - 将字母转换为数字和符号
- c# - 来自 TcpClient 的 TcpState
- php - 为什么有时mysql会更新两次
- angular - angular 6 获取拦截器内的响应标头