如何在Kotlin中返回接收参数的suspend函数?
Kotlin:将带参数的非suspend函数转为同步suspend函数的通用方法
前置条件:所有示例均需定义Mutex变量
val mutex = Mutex()
单个无参数非suspend函数转同步suspend函数
无参数的非suspend函数可通过mutex.withLock包装为线程安全的suspend函数:
fun action0() {} suspend fun synchronizedAction0() { mutex.withLock { action0() } }
单个带参数非suspend函数转同步suspend函数
带参数的函数逻辑一致,直接在suspend函数中接收参数并传入原函数即可:
fun action1(x: T) {} suspend fun synchronizedAction1(x: T) { mutex.withLock { action1(x) } }
通用包装函数(无参数场景)
如果有多个非suspend函数需要批量包装,可以编写通用函数,接收无参数函数并返回对应的同步suspend函数:
fun synchronize(action0: () -> Unit): suspend () -> Unit { return suspend { mutex.withLock { action0() } } }
问题:带参数的通用包装函数如何编写?
尝试以下两种写法时均无法编译,编译器无法推断参数x的类型:
// 写法1:lambda表达式返回 fun synchronize(action1: (T) -> Unit): suspend (T) -> Unit { return suspend { x -> mutex.withLock { action1(x) } } } // 写法2:匿名函数返回 fun synchronize(action1: (T) -> Unit): suspend (T) -> Unit { return suspend fun (x: T) { mutex.withLock { action1(x) } } }
正确语法:添加泛型参数声明
核心问题是未给synchronize函数声明泛型参数T,编译器无法识别T的来源。只需在函数名前添加<T>泛型声明,即可让编译器关联原函数与返回suspend函数的参数类型:
写法1:lambda表达式返回(明确参数类型)
fun <T> synchronize(action1: (T) -> Unit): suspend (T) -> Unit { return suspend { x: T -> mutex.withLock { action1(x) } } }
写法2:匿名函数返回
fun <T> synchronize(action1: (T) -> Unit): suspend (T) -> Unit { return suspend fun(x: T) { mutex.withLock { action1(x) } } }
简化写法(利用类型推断)
添加泛型声明后,编译器可自动推断参数类型,可省略x的类型标注:
fun <T> synchronize(action1: (T) -> Unit): suspend (T) -> Unit { return suspend { x -> mutex.withLock { action1(x) } } }
内容的提问来源于stack exchange,提问作者ceving
相关产品推荐
相关产品推荐

