反射地引用重载的顶级Kotlin函数



简而言之,如何在Kotlin中引用/迭代重载的顶级函数,比如kotlin.io.println?


给定以下内容:

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

我可以遍历foo的各种重载:

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

生产:

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

然而,如果foo的各种重载被定义为顶层(在类或对象定义之外),例如:

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

那么似乎没有办法引用它们。

我尝试在我的示例中使用顶级函数(例如main)来访问合成类:

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

但它呕吐于它是合成的事实:

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.

如何在Kotlin中引用顶级重载函数?

更具体地说,在其他包/模块中定义的顶级重载函数,如kotlin.io.println?

顶层函数根据定义没有声明类。

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

,所以你没有一个类来使用反射,因此,你不能枚举包的顶层成员。(如果你愿意用你的灵魂来交换,一些魔法是可以做到的)

你可以引用有歧义的顶级函数的唯一方法是帮助编译器解决歧义,像这样:

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

然后调用functionReference()

最新更新