带有 vararg 参数的 kotlin 参考函数并将 Array<out 转换为 List<out

kotlin reference function with vararg parameter and convert Array<out to List<out

我已经根据这个主题提出了问题 Base Question

所以,我想提前问一下。 有人用 Array 和 List

回答了问题
Class Test<T,V>{
   var functionPara :(()->T)? = null
   var recallFunctionWithFunction:( (Array<out T>) -> V)? = null

   constructor(value: ()->T, recallFunctionWithFunction:   (Array<out T>) -> V  ){
   this.functionPara = value
   this.recallFunctionWithFunction = recallFunctionWithFunction
}
inline fun <reified T, V> compose(crossinline f: (Array<out T>) -> V, vararg g: () -> T): () -> V {
val results = g.map { it() }
return { f(results.toTypedArray()) }
}

fun <T, V> compose(f: (List<out T>) -> V, vararg g: () -> T): () -> V {
val results = g.map { it() }
return { f(results) }
}
}
fun runCompose(){
compose(functionPara,recallFunctionWithFunction).invoke()
}

但我发现当我引用一个带有 vararg 参数的函数时

fun functionA(vararg :Observable<Any>):LiveData<Boolean>{
}
fun functionB():Observable<Any>{
}

当我执行类似 ::functionA 的操作时,A 的类型将为 Array<out Observable<Any>>->LiveData<Boolean> 因此,当我执行类似操作时

Test<Observable<Any>,LiveData<Boolean>>(::functionB,::functionA).runCompose()

情况一 如果我使用接受 List 类型的 compose 函数,它将显示类型不匹配,因为引用 ::functionA will return Array

情况2 如果我使用接受数组类型的撰写函数,它将显示错误

不能使用 'T' 作为具体化的类型参数。使用 class 代替

在之前的post中,有人回答我将数组转换为列表。但是如何使用 Originally Array<out to List <out 转换带有 vararg 参数的引用函数? 当我引用像 ::function 这样的函数时,类型必须是 Array<out 但我想将其插入撰写功能。我必须转换它。 谁能帮忙?我在那里呆了很长时间。希望有人能救救我!!

由于类型擦除,您无法将列表转换为类型化数组。我认为最简单的方法是到处使用 List

class Test<T, V>(val recallFunctionWithFunction: (List<T>) -> V, val functionPara: () -> T) {

    inline fun compose(crossinline f: (List<T>) -> V, vararg g: () -> T): () -> V {
        return { f(g.map { it.invoke() }) }
    }

    fun runCompose() {
        compose(recallFunctionWithFunction, functionPara).invoke()
    }
}

fun functionA(l: List<Observable<Any>>): LiveData<Boolean> {
...
}
fun functionB(): Observable<Any> {
...
}

另一个解决方案

class Test<T, V>(
    val recallFunctionWithFunction: (Array<out T>) -> V,
    val functionPara: () -> T,
    val clazz: Class<T>
) {

    companion object {
        inline fun <reified T, V> create(
            noinline recallFunctionWithFunction: (Array<out T>) -> V,
            noinline functionPara: () -> T
        ) = Test(recallFunctionWithFunction, functionPara, T::class.java)
    }

    inline fun compose(crossinline f: (Array<out T>) -> V, vararg g: () -> T): () -> V {
        return {
            @Suppress("UNCHECKED_CAST")
            val arr = java.lang.reflect.Array.newInstance(clazz, g.size) as Array<T>
            g.forEachIndexed { index, fg -> arr[index] = fg.invoke() }
            f(arr)
        }
    }

    fun runCompose() {
        compose(recallFunctionWithFunction, functionPara).invoke()
    }
}

...
val t = Test.create(::functionA, ::functionB)
t.runCompose()