Home > front end >  any function type used in kotlin
any function type used in kotlin

Time:10-10

we can easily define a function like:

fun <T> f1(f2: KFunction<T>) {…}

then call it like this:

fun f2() {...}
f1(::f2)

but when I want to call it like this:

f1 {

}

it failed. because it required KFunction<TypeVariable>, but it is actually () -> Unit.

so I rewrite it like this:

fun <K, T : Function<K>> f1(args: Array<Any> = arrayOf(), f2: T) {
    //f2.invoke(args)
    //it failed. I don't know how to call f2
}

f1 {…} //success

So this is the problem. I don't know how to call an arbitary anonymous function type

And I try to call it this way:

inline fun <K, reified T : Function<K>> f1(args: Array<Any> = arrayOf(), f2: T) {
    val typeParams = args.map { it::class.java }.toTypedArray()
    T::class.java.getDeclaredMethod("invoke", *typeParams).invoke(f2, args) 
    // success. But I don't know if there is a bug
}

At last, I find kotlin.reflect.jvm.Function.reflect() But it is useless now. So I want to know if there is a better way to do this.

Thanks for any help.

CodePudding user response:

This is my final solution. It is generated by a generator. It looks stupid but it is very useful

@Suppress("UNCHECKED_CAST")
fun Function<*>.call(vararg args: Any?): Any? {
    return when(this) {
        is Function0 -> {
            invoke()
        }
        is Function1<*,*> -> {
            (this as Function1<Any?,Any?>).invoke(args[0])
        }
        is Function2<*,*,*> -> {
            (this as Function2<Any?,Any?,Any?>).invoke(args[0],args[1])
        }
        is Function3<*,*,*,*> -> {
            (this as Function3<Any?,Any?,Any?,Any?>).invoke(args[0],args[1],args[2])
        }
        is Function4<*,*,*,*,*> -> {
            (this as Function4<Any?,Any?,Any?,Any?,Any?>).invoke(args[0],args[1],args[2],args[3])
        }
        is Function5<*,*,*,*,*,*> -> {
            (this as Function5<Any?,Any?,Any?,Any?,Any?,Any?>).invoke(args[0],args[1],args[2],args[3],args[4])
        }
        is Function6<*,*,*,*,*,*,*> -> {
            (this as Function6<Any?,Any?,Any?,Any?,Any?,Any?,Any?>).invoke(args[0],args[1],args[2],args[3],args[4],args[5])
        }
        is Function7<*,*,*,*,*,*,*,*> -> {
            (this as Function7<Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?>).invoke(args[0],args[1],args[2],args[3],args[4],args[5],args[6])
        }
        is Function8<*,*,*,*,*,*,*,*,*> -> {
            (this as Function8<Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?>).invoke(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7])
        }
        is Function9<*,*,*,*,*,*,*,*,*,*> -> {
            (this as Function9<Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?>).invoke(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8])
        }
        is Function10<*,*,*,*,*,*,*,*,*,*,*> -> {
            (this as Function10<Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?>).invoke(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9])
        }
        is Function11<*,*,*,*,*,*,*,*,*,*,*,*> -> {
            (this as Function11<Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?>).invoke(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10])
        }
        is Function12<*,*,*,*,*,*,*,*,*,*,*,*,*> -> {
            (this as Function12<Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?>).invoke(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11])
        }
        is Function13<*,*,*,*,*,*,*,*,*,*,*,*,*,*> -> {
            (this as Function13<Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?>).invoke(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12])
        }
        is Function14<*,*,*,*,*,*,*,*,*,*,*,*,*,*,*> -> {
            (this as Function14<Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?>).invoke(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13])
        }
        is Function15<*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*> -> {
            (this as Function15<Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?>).invoke(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14])
        }
        is Function16<*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*> -> {
            (this as Function16<Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?>).invoke(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15])
        }
        is Function17<*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*> -> {
            (this as Function17<Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?>).invoke(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16])
        }
        is Function18<*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*> -> {
            (this as Function18<Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?>).invoke(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17])
        }
        is Function19<*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*> -> {
            (this as Function19<Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?>).invoke(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18])
        }
        is Function20<*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*> -> {
            (this as Function20<Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?>).invoke(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19])
        }
        is Function21<*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*> -> {
            (this as Function21<Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?>).invoke(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20])
        }
        is Function22<*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*> -> {
            (this as Function22<Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?,Any?>).invoke(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21])
        }
        is FunctionN<*> -> {
            (this as FunctionN<Any?>).invoke(*args)
        }

        else -> { throw RuntimeException() }
    }
}
  • Related