如何解决Kotlin高阶函数签名类型:匹配的函数对象和类型擦除
似乎我在这里错过了一些非常重要的事情。 Kotlin函数类型使用称为 Function N 的特定类实现,并使用泛型定义接收器,参数和返回类型。存储函数引用时,是否存在可以保留函数签名的语法?还是任何其他方式可以执行下面代码中的工作?
这是因为这都是娱乐和游戏,直到您希望精简地 存储以输入任何,例如在{{1 }},然后检索它们,将它们匹配并向下转换/分配给一个功能变量并使用它。问题在于泛型会执行 类型擦除 ,因此,如果您将函数存储到 Any ,则无法找回并使用它,即使其与Map<String,Any>
匹配,则实际类型为:
Function2<Int,Int,Int>
,因此无法使用,因为它仅将签名与Nothing类型的参数匹配,即您已经完成了。 (您只能使用Function2<*,*,*>
,因为它没有参数或返回类型。)
在编译类型函数签名和运行时函数签名之间似乎没有联系。
由于样板以及我必须使用类继承来键入函数签名的事实,我设法通过以下我讨厌的代码克服了这一点。我知道强制转换要求代码对存储的对象有额外的了解,并且可以将其视为反模式,但是还应如何存储功能以便以后进行动态调用? (可能存在与应用程序/服务器上的参数和类型匹配的其他数据,其他模块都将声明其自己的功能。在下面的示例中,类仅声明了一个与签名类型绑定的功能,在完整的示例中这些类将在构造函数中使用实际的lambda值,即Function0
的每个实例都指向另一个函数,因此它的深度为2级:签名和函数指针。
感谢您的亲切见解和建议。
编辑:说明和拼写
Function2IntToInt
解决方法
由于JVM的类型擦除,存储在多个子类型的集合中的任何类型都将面临相同的问题。在这种情况下,铸造是不可避免的。使用函数,您将必须创建种类更多的包装器类型,就像必须能够按类型检索它们一样。通过在类型为键的地图中按类型将项目存储在单独的列表中,可以更好地实现防呆。
val foo = mutableMapOf<Func,MutableMap<String,Func>>()
fun <T: Func> storeItem(item: T,name: String) {
foo.getOrPut(bar::class,::mutableMapOf)[name] = item
}
inline fun <reified T: Func> retrieveItem(name: String): T? {
return foo[T::class]?.get(name) as T?
}
请注意,您严格不需要Func
超级类型。您可以在上面的代码中用Any替换它,并使您的实现直接从其功能定义继承:
abstract class FunctionStringToInt: (String) -> Int
class MyStringToIntImpl: FunctionStringToInt() {
override fun invoke(s: String): Int {
return s.length
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。