gpt4 book ai didi

kotlin - 如何将 rxjava2 Zip 函数(从 Single/Observable)的数量概括为 n 个 Nullable 参数而不丢失其类型?

转载 作者:行者123 更新时间:2023-12-01 10:35:13 31 4
gpt4 key购买 nike

要解决的两个主要问题:
1) 类型检查丢失
使用数组参数 Single.zip()版本我失去了强类型参数。
2) 源参数不能为空
我无法发送可空源值作为 Single.zip() 的参数功能
3) 我想要一个替代方法来使用 Object[]未输入:
4) 我不想要可变对象 , 我不想使用 变量 在我的类里面,我想使用

public static <T, R> Single<R> zipArray(Function<? super Object[], ? extends R> zipper, SingleSource<? extends T>... sources) ...
在haskell,有一个问题相关 How can I implement generalized "zipn" and "unzipn" in Haskell? :
在 haskell 中,我可以使用应用仿函数来实现这一点:
f <$> a1 <*> a2 <*> a3 <*> a4 <*> a5 <*> a6 <*> a7 <*> a8 <*> a9 <*> a10 <*> a11
正在 f :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> String -> String -> String -> Inta1 .. a11每种类型对应的值
库中有一个类似函数的列表:
  • 有两个论点:
     public static <T1, T2, R> Single<R> zip(SingleSource<? extends T1> source1, SingleSource<? extends T2> source2,BiFunction<? super T1, ? super T2, ? extends R> zipper) {
    ObjectHelper.requireNonNull(source1, "source1 is null");
    ObjectHelper.requireNonNull(source2, "source2 is null");
    return zipArray(Functions.toFunction(zipper), source1, source2);
    }
  • 三个:
      public static <T1, T2, T3, R> Single<R> zip(
    SingleSource<? extends T1> source1, SingleSource<? extends T2> source2,
    SingleSource<? extends T3> source3,
    Function3<? super T1, ? super T2, ? super T3, ? extends R> zipper)

  • 等等...
    在所有这些情况下,都很好,因为每个参数都是输入的。 但是有一个限制,直到 9 个单一来源
    在我们的项目中,我们需要更多的资源,因为我们有很多服务需要异步(在我们的例子中是 11 个参数)。
    但问题是参数失去了它们的强类型,更糟糕的是,其中一些可能是 可空
    例如,我们想解决这个用例:
    //Given
    val bothSubscribed = CountDownLatch(2) // Change this value to 0 to run the test faster
    val subscribeThreadsStillRunning = CountDownLatch(1) // Change this value to 0 to run the test faster

    val service = { s1: String,
    s2: Int,
    s3: String?,
    s4: Int,
    s5: String,
    s6: String,
    s7: String,
    s8: String,
    s9: String,
    s10: String?,
    s11: String ->
    val result =
    listOf(s1, "$s2", s3 ?: "none", "$s4", s5, s6, s7, s8, s9, s10 ?: "none", s11).joinToString(separator = ";")
    Single.just("Values:$result")
    }

    val createSingle = { value: String ->
    Observable
    .create<String> { emitter ->
    println("Parallel subscribe $value on ${Thread.currentThread().name}")
    bothSubscribed.countDown()
    subscribeThreadsStillRunning.await(20, TimeUnit.SECONDS)
    emitter.onNext(value)
    emitter.onComplete()
    }
    .singleOrError()
    .subscribeOn(io())
    }

    val s1 = createSingle("v1")
    val s2 = Single.just(2)
    val s3 = null
    val s4 = Single.just(4)
    val s5 = createSingle("v5")
    val s6 = createSingle("v6")
    val s7 = createSingle("v7")
    val s8 = createSingle("v8")
    val s9 = createSingle("v9")
    val s10 = null
    val s11 = createSingle("v11")

    //When

    val result = Single.zipArray(
    listOf(
    s1,
    s2,
    s3,
    s4,
    s5,
    s6,
    s7,
    s8,
    s9,
    s10,
    s11
    )
    ) { arrayResult ->
    service(
    arrayResult[0] as String,
    arrayResult[1] as String,
    arrayResult[2] as String?,
    arrayResult[3] as String,
    arrayResult[4] as String,
    arrayResult[5] as String,
    arrayResult[6] as String,
    arrayResult[7] as String,
    arrayResult[8] as String,
    arrayResult[9] as String?,
    arrayResult[10] as String
    )
    }

    //Then
    result
    .test()
    .awaitDone(50, TimeUnit.SECONDS)
    .assertSubscribed()
    .assertValues("Values:v1;2;none;4;v5;v6;v7;v8;v9;none;v11")
    如您所见,如果我这样做可能会出现问题,例如:
    arrayResult[0] as String,
    arrayResult[1] as Int,
    arrayResult[2] as String?,
    arrayResult[3] as Int,
    arrayResult[4] as String,
    arrayResult[5] as String,
    arrayResult[6] as String,
    arrayResult[7] as String,
    arrayResult[8] as String,
    arrayResult[9] as String?,
    arrayResult[10] as String
    失败是因为:
    1) 没有 Single.zip()函数可以将一个可为空的值作为参数。
    2)您可以在数组中更改值的顺序,它可能会因为类型检查强制转换而失败

    最佳答案

    具有 11 个参数的函数是不干净代码的一个很好的例子。相反,您应该考虑构建一个模型来满足您的需求。像这样,您也可以为每个参数提供有意义的名称。

    data class MyObject(...)

    class MyMutableObject {
    private lateinit var param0: String
    private var param1: Int
    ...

    fun setParam0(value: String) {
    param0 = value
    }
    fun setParam1(value: Int) {
    param1 = value
    }
    ...

    fun toMyObject() = MyObject(
    param0,
    param1,
    ...
    )
    }
    有了这个模型,你可以使用 zipWith()您的每个来源的运营商。
    Single.just(MyMutableObject())
    .zipWith(source0, MyMutableObject::setParam0)
    .zipWith(source1, MyMutableObject::setParam1)
    ...
    .map(MyMutableObject::toMyObject)
    如果您考虑将可空性抽象为 Maybe ,您可以简单地定义一个接收 Maybe 的扩展函数有数据或无数据,并适本地映射它。
    inline fun <T, U, R> Single<T>.zipWith(
    other: MaybeSource<U>,
    crossinline zipper: (T, U) -> R
    ) = other.zipWith(toMaybe()) { t, u -> zipper(t, u) }
    .switchIfEmpty(this)

    关于kotlin - 如何将 rxjava2 Zip 函数(从 Single/Observable)的数量概括为 n 个 Nullable 参数而不丢失其类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62844759/

    31 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com