Kotlin:使用 get/set 运算符具体化泛型的 UnsupportedOperationException
Kotlin: UnsupportedOperationException for reified generic with get/set operator
我正在尝试将库中的函数 read
和 write
分别转换为运算符函数 get
和 set
。我的函数使用具体化的泛型类型,它们也是内联方法。 (你可以看到我的图书馆here。)
编译器没有问题让我通过,我不明白为什么使用非运算符函数推理工作正常,但使用运算符在 运行 时失败。
Exception in thread "main" java.lang.UnsupportedOperationException: This function has a reified type parameter and thus can only be inlined at compilation time, not called directly.
at kotlin.jvm.internal.Intrinsics.throwUndefinedForReified(Intrinsics.java:173)
at kotlin.jvm.internal.Intrinsics.throwUndefinedForReified(Intrinsics.java:167)
at kotlin.jvm.internal.Intrinsics.reifyJavaClass(Intrinsics.java:201)
代码如下:
operator inline fun <reified T> get(address: Long): T {
...
}
operator inline fun <reified T> get(address: Int): T = get(address.toLong())
operator inline fun <reified T> set(address: Long, data: T) {
...
}
operator inline fun <reified T> set(address: Int, data: T): Unit = set(address.toLong(), data)
有趣的是,我可以用中缀函数很好地做到这一点,例如:
class Example { infix inline fun <reified T> foo(bar: Int) = Any() as T }
fun main(args: Array<String>) {
val example = Example()
val foobar: Any = example foo 12345
}
我也可以用其他运算符来做这个,例如这两个都有效:
operator inline fun <reified T> minus(bar: Int) = foo<T>(bar)
operator inline fun <reified T> plus(bar: Int) = foo<T>(bar)
我还注意到 invoke
也能正常工作!这很奇怪,因为 invoke
和 get
似乎都有相同的实现。
operator inline fun <reified T> invoke(bar: Int) = foo<T>(bar)
但是如果我将以下函数添加到示例中:operator inline fun <reified T> get(bar: Int) = foo<T>(bar)
然后尝试以下调用我 运行 进入错误:val get: Any = example[12345]
这是一个错误:https://youtrack.jetbrains.com/issue/KT-9211
作为解决方法,使用 .get(...)
而不是 [...]
我正在尝试将库中的函数 read
和 write
分别转换为运算符函数 get
和 set
。我的函数使用具体化的泛型类型,它们也是内联方法。 (你可以看到我的图书馆here。)
编译器没有问题让我通过,我不明白为什么使用非运算符函数推理工作正常,但使用运算符在 运行 时失败。
Exception in thread "main" java.lang.UnsupportedOperationException: This function has a reified type parameter and thus can only be inlined at compilation time, not called directly.
at kotlin.jvm.internal.Intrinsics.throwUndefinedForReified(Intrinsics.java:173)
at kotlin.jvm.internal.Intrinsics.throwUndefinedForReified(Intrinsics.java:167)
at kotlin.jvm.internal.Intrinsics.reifyJavaClass(Intrinsics.java:201)
代码如下:
operator inline fun <reified T> get(address: Long): T {
...
}
operator inline fun <reified T> get(address: Int): T = get(address.toLong())
operator inline fun <reified T> set(address: Long, data: T) {
...
}
operator inline fun <reified T> set(address: Int, data: T): Unit = set(address.toLong(), data)
有趣的是,我可以用中缀函数很好地做到这一点,例如:
class Example { infix inline fun <reified T> foo(bar: Int) = Any() as T }
fun main(args: Array<String>) {
val example = Example()
val foobar: Any = example foo 12345
}
我也可以用其他运算符来做这个,例如这两个都有效:
operator inline fun <reified T> minus(bar: Int) = foo<T>(bar)
operator inline fun <reified T> plus(bar: Int) = foo<T>(bar)
我还注意到 invoke
也能正常工作!这很奇怪,因为 invoke
和 get
似乎都有相同的实现。
operator inline fun <reified T> invoke(bar: Int) = foo<T>(bar)
但是如果我将以下函数添加到示例中:operator inline fun <reified T> get(bar: Int) = foo<T>(bar)
然后尝试以下调用我 运行 进入错误:val get: Any = example[12345]
这是一个错误:https://youtrack.jetbrains.com/issue/KT-9211
作为解决方法,使用 .get(...)
而不是 [...]