Kotlin如何将任意函数及其参数传入可复用处理函数
实现通用的失败重试处理函数(Kotlin)
你可以利用Kotlin的高阶函数和泛型来实现这个通用的错误处理重试逻辑,避免重复代码。核心思路是用lambda捕获原函数的调用(包括参数),通过泛型适配任意返回类型,用谓词判断是否需要重试。
解决方案代码
1. 原函数定义
fun foo(a: Any): Any? { // 模拟业务操作,失败返回null return null } fun bar(b: Any, c: Any): Boolean { // 模拟业务操作,失败返回false return false }
2. 通用重试处理函数
import org.slf4j.LoggerFactory private val log = LoggerFactory.getLogger("ErrorHandler") /** * 通用失败处理重试函数 * @param functionName 原函数名称(用于日志输出) * @param shouldRetry 判断是否需要重试的条件(基于原函数返回值) * @param actionA 失败后执行的动作A * @param function 要执行的原函数调用(通过lambda捕获参数) * @return 原函数(或重试后的)返回值 */ fun <T> handleFailureAndRetry( functionName: String, shouldRetry: (T) -> Boolean, actionA: () -> Unit, function: () -> T ): T { val result = function() if (shouldRetry(result)) { log.warn("Error has been caught at <$functionName>, doing action A and retrying") // 执行动作A的逻辑,比如清理资源、发送通知等 actionA() log.warn("Retrying <$functionName>") // 重试原函数 return function() } return result }
3. 简化调用(可选扩展)
如果需要更简洁的调用,可以针对常见的失败场景(返回null、返回false)封装扩展函数:
// 适配返回Nullable类型的函数:返回null时触发重试 fun <T> handleNullFailureAndRetry( functionName: String, actionA: () -> Unit, function: () -> T? ): T? { return handleFailureAndRetry( functionName = functionName, shouldRetry = { it == null }, actionA = actionA, function = function ) } // 适配返回Boolean类型的函数:返回false时触发重试 fun handleBooleanFailureAndRetry( functionName: String, actionA: () -> Unit, function: () -> Boolean ): Boolean { return handleFailureAndRetry( functionName = functionName, shouldRetry = { !it }, actionA = actionA, function = function ) }
4. 调用示例
fun main() { // 处理foo的失败重试 val resultFoo = handleNullFailureAndRetry( functionName = "foo", actionA = { /* 这里写动作A的具体逻辑 */ }, function = { foo("bar") } ) // 处理bar的失败重试 val resultBar = handleBooleanFailureAndRetry( functionName = "bar", actionA = { /* 复用动作A的逻辑 */ }, function = { bar("foo", mapOf("foo" to "bar")) } ) }
方案优势
- 完全泛化:支持任意签名、任意返回类型的函数,不用为每个函数单独写处理逻辑
- 逻辑复用:动作A和重试逻辑只需要写一次,所有函数共享
- 灵活适配:通过
shouldRetry谓词可以自定义失败判断条件(比如特定错误码、异常等) - 简洁调用:用lambda捕获原函数参数,不需要手动维护参数数组
内容的提问来源于stack exchange,提问作者Mario
相关产品推荐
相关产品推荐

