简体   繁体   English

引用重载的顶层 Kotlin 反射功能

[英]Referencing overloaded top-level Kotlin functions reflectively

In brief, how can one reference / iterate reflectively over overloaded top-level functions in Kotlin, such as kotlin.io.println ?简而言之,如何对 Kotlin 中的重载顶级函数进行反射性引用/迭代,例如kotlin.io.println


Given the following:鉴于以下情况:

object Bar {
    fun foo(x: Int) = Unit
    fun foo(x: Byte) = Unit
    fun foo(x: Float) = Unit
}

I can iterate over the various overloads of foo by doing:我可以通过执行以下操作迭代foo的各种重载:

fun main() {
    Bar::class.memberFunctions
        .filter { kFunction -> kFunction.name == "foo" }
        .forEach { kFunction -> println(kFunction) }
}

Which produces:产生:

fun com.example.Bar.foo(kotlin.Byte): kotlin.Unit
fun com.example.Bar.foo(kotlin.Float): kotlin.Unit
fun com.example.Bar.foo(kotlin.Int): kotlin.Unit

However , if the various overloads of foo are defined top-level ( outside of a class or object definition ) such as simply:但是,如果foo的各种重载被定义为顶级(在 class 或 object 定义之外),例如:

fun foo(x: Int) = Unit
fun foo(x: Byte) = Unit
fun foo(x: Float) = Unit

Then there doesn't seem to be a way to reference them.然后似乎没有办法引用它们。

I tried being tricky using a top-level function in my example ( such as main ) to access the synthetic class:我尝试在我的示例中使用顶级 function(例如main )来访问合成 class,这很棘手:

::main::class.memberFunctions
    .filter { kFunction -> kFunction.name == "foo" }
    .forEach { kFunction -> println(kFunction) }

But it pukes on the fact that it's synthetic:但它呕吐的事实是它是合成的:

Exception in thread "main" java.lang.UnsupportedOperationException: This class is an internal synthetic class generated by the Kotlin compiler, such as an anonymous class for a lambda, a SAM wrapper, a callable reference, etc. It's not a Kotlin class or interface, so the reflection library has no idea what declarations does it have. Please use Java reflection to inspect this class.

How can I reference top-level overloaded functions in Kotlin?如何引用 Kotlin 中的顶级重载函数?

More specifically, top-level overloaded functions defined in other packages / modules such as kotlin.io.println ?更具体地说,在其他包/模块中定义的顶级重载函数,例如kotlin.io.println

Top level functions by definition don't have a declaring class.根据定义,顶级函数没有声明 class。

::println.javaClass.declaringClass //will return null

so you don't have a class to use reflection on, and consequently, you can't enumerate the top level members of a package.( Some magic can be done though, if you are willing to trade your soul )所以你没有 class 来使用反射,因此,你不能枚举 package 的顶级成员。(如果你愿意交易你的灵魂,可以做一些魔法

The only way you can reference ambiguous top level functions is by helping the compiler to resolve the ambiguity like this:引用模棱两可的顶级函数的唯一方法是帮助编译器解决歧义,如下所示:

val functionReference: (Int)->Unit = ::foo

and then you can call functionReference()然后你可以调用 functionReference()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM