Kotlin Flow:为什么函数 merge() 最多只能接受 5 个流的参数

Lux*_*Liu 21 coroutine kotlin kotlin-coroutines kotlin-flow

我注意到,combine() 函数最多只能接受 5 个流的参数

public fun <T1, T2, T3, T4, T5, R> combine(
    flow: Flow<T1>,
    flow2: Flow<T2>,
    flow3: Flow<T3>,
    flow4: Flow<T4>,
    flow5: Flow<T5>,
    transform: suspend (T1, T2, T3, T4, T5) -> R
): Flow<R> = combineUnsafe(flow, flow2, flow3, flow4, flow5) { args: Array<*> ->
    transform(
        args[0] as T1,
        args[1] as T2,
        args[2] as T3,
        args[3] as T4,
        args[4] as T5
    )
}
Run Code Online (Sandbox Code Playgroud)

这背后有什么特殊原因吗?(或者可能不是?)

如果我在本地文件中定义一个有6个参数的combine(),例如

private fun <T1, T2, T3, T4, T5, T6, R> combine(
    flow: Flow<T1>,
    flow2: Flow<T2>,
    flow3: Flow<T3>,
    flow4: Flow<T4>,
    flow5: Flow<T5>,
    flow6: Flow<T6>,
    transform: suspend (T1, T2, T3, T4, T5, T6) -> R
): Flow<R> = combine(flow, flow2, flow3, flow4, flow5, flow6) { args: Array<*> ->
    transform(
        args[0] as T1,
        args[1] as T2,
        args[2] as T3,
        args[3] as T4,
        args[4] as T5,
        args[5] as T6
    )
}
Run Code Online (Sandbox Code Playgroud)

这可能有任何潜在的问题吗?

谢谢你!

com*_*m1x 15

我猜类型安全的组合扩展(用于 2-5 个流)只是 common 的语法糖combine(vararg flows)。所以执行时不会有任何惩罚combine

实施combine需要 6 个流程,无需任何成本。

inline fun <T1, T2, T3, T4, T5, T6, R> combine(
    flow: Flow<T1>,
    flow2: Flow<T2>,
    flow3: Flow<T3>,
    flow4: Flow<T4>,
    flow5: Flow<T5>,
    flow6: Flow<T6>,
    crossinline transform: suspend (T1, T2, T3, T4, T5, T6) -> R
): Flow<R> {
    return kotlinx.coroutines.flow.combine(flow, flow2, flow3, flow4, flow5, flow6) { args: Array<*> ->
        @Suppress("UNCHECKED_CAST")
        transform(
            args[0] as T1,
            args[1] as T2,
            args[2] as T3,
            args[3] as T4,
            args[4] as T5,
            args[5] as T6,
        )
    }
}
Run Code Online (Sandbox Code Playgroud)

这是实现组合中的原始方法: 在此输入图像描述


ltp*_*ltp 10

您可以使用 kotlin lib 中的基本组合函数:

   public inline fun <reified T, R> combine(
        vararg flows: Flow<T>,
        crossinline transform: suspend (Array<T>) -> R
    ): Flow<R> = flow {
        combineInternal(flows, { arrayOfNulls(flows.size) }, { emit(transform(it)) })
    }
Run Code Online (Sandbox Code Playgroud)

如果组合不同类型的流,请使用强制转换,例如:

val myDataModel= combine(
    firstParamBooleanFlow,
    secondParamBooleanFlow,
    thirdParamStringFlow,
    fourthParamStringFlow,
    fifthParamIntFlow,
    sixthParamIntFlow
){array ->
    DataModel( 
        isTrue = array[0] as Boolean && array[1] as Boolean,
        title = "${array[2]} - ${array[3]}",
        count = array[4] as Int + array[5]  as Int
        )
}
Run Code Online (Sandbox Code Playgroud)