我已经根据这个主题 基本问题提出了问题

所以,我想提前问一下。有人用数组和列表回答了这个问题

Class Test<,android,kotlin,generics,reflection,variadic-functions"/>
	














首页 > 解决方案 > 带有可变参数和转换数组的 kotlin 参考函数

我已经根据这个主题 基本问题提出了问题

所以,我想提前问一下。有人用数组和列表回答了这个问题

Class Test<

问题描述

我已经根据这个主题 基本问题提出了问题

所以,我想提前问一下。有人用数组和列表回答了这个问题

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

图片1

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

不能使用“T”作为具体类型参数。改用一个类

图片2

在上一篇文章中,有人回答我将数组转换为列表。但是如何将带有可变参数参数的引用函数转换为原始Array<out to List <out?当我引用 ::function 之类的函数时,类型必须是Array<out ,但我想将其插入 compose 函数中。我必须转换它。任何人都可以帮忙吗?我在那儿呆了很长时间。希望有人能救我!!


那么,谁相信呢?用户错误!在我的 css 覆盖中,我给类 'fc-unselectable' 赋予了 '#fff' 的 colo(u)r,这不仅导致标题和时间栏,而且还导致日历事件中没有的任何文本“消失”。当然,当时我会测试此覆盖的效果,因此假设从那时起的其他一些更改导致了不需要的行为。现在我绞尽脑汁想弄清楚为什么我一开始就觉得白色字体是必要的。将来必须在我的代码中添加更详细的注释...

标签: androidkotlingenericsreflectionvariadic-functions

解决方案


由于类型擦除,您无法将列表转换为类型化数组。我认为最简单的方法是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()

推荐阅读