kotlin引用函数,带vararg参数,并将Array<out转换为List<out。

问题描述 投票:1回答:1

我是根据这个题目提出问题的 基本问题

所以,我想提前问一下,有人用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()

情况1如果我在接受List类型的情况下使用compose函数,由于引用::functionA会返回Array,所以会显示类型不匹配。

Image1

情况2如果我在接受Array类型的情况下使用compose函数,就会出现以下错误

不能使用'T'作为重定类型参数。请使用类代替

Image2

在之前的帖子中,有人回答我说把数组转换为列表。但如何将带有vararg参数的引用函数与原来的引用函数进行转换呢?Array<out to List <out 当我引用一个函数如::函数时,类型必须是 Array<out但我想把它插入到组成功能。我必须转换它.任何人都可以帮助我卡在那里长天。希望有人能救我!!!!!!!!!。

android kotlin generics reflection variadic-functions
1个回答
1
投票

由于类型擦除的原因,你不能将一个列表转换为一个类型化的数组。我认为最简单的方法是使用 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()
© www.soinside.com 2019 - 2024. All rights reserved.