带有 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()
我已经根据这个主题提出了问题 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()