Kotlin编译与泛型和自动类型转换有关的错误
我认为这个代码片段应该编译:
package bug import java.lang.reflect.* data class Descriptor(val clazz: Class<*>, val modifiers: Int, val info: List<String>) { constructor(clazz: Class<*>, modifiers: Int, vararg info: List<String>) : this(clazz, modifiers, mutableListOf<String>().apply { info.forEach { this@apply.addAll(it) } }) } private val AnnotatedElement.info: List<String> get() = getAnnotation(Info::class.java)?.values?.toList() ?: listOf<String>() annotation class Info(val values: Array<String>) /** * A simple abstraction of com.google.common.reflect.Invokable of Guava 20.0. * https://github.com/google/guava/blob/v20.0/guava/src/com/google/common/reflect/Invokable.java */ abstract class Invokable<T, R> : AccessibleObject(), Member, GenericDeclaration val <T : AccessibleObject> T.descriptor: Descriptor get() = when (this) { is Invokable<*, *> -> Descriptor(declaringClass, modifiers, info, declaringClass.info) else -> throw AssertionError() }
这里是一个方便的参考谷歌Guava的可Invokable 。 简要给出了可定义的定义。
上面的代码应该编译好,但编译器会产生3个奇怪的消息,这里是日志输出(经过适当的规范化):
e:/path/to/source.kt:(34,44):类型推断失败:val Invokable.declaringClass:Class! 不能应用于接收者:T#2(描述符的类型参数)参数:()
e:/path/to/source.kt:(35,44):类型推断失败:val Invokable.modifiers:Int不能应用于接收者:T#2(描述符的类型参数)参数:
e:/path/to/source.kt:(37,44):类型推断失败:val Invokable.declaringClass:Class! 不能应用于接收者:T#2(描述符的类型参数)参数:()
解决方法很简单:将其分配给一个变量并使用该局部变量。 没有手动类型转换或其他麻烦的东西,它会编译。 但是, 如果这是一个kotlin编译器的错误,或者我错过了关于kotlin泛型的一些信息,我很感兴趣
编辑:工作代码:
package solution import java.lang.reflect.* data class Descriptor(val clazz: Class<*>, val modifiers: Int, val info: List<String>) { constructor(clazz: Class<*>, modifiers: Int, vararg info: List<String>) : this(clazz, modifiers, mutableListOf<String>().apply { info.forEach { this@apply.addAll(it) } }) } private val AnnotatedElement.info: List<String> get() = getAnnotation(Info::class.java)?.values?.toList() ?: listOf<String>() annotation class Info(val values: Array<String>) /** * A simple abstraction of com.google.common.reflect.Invokable of Guava 20.0. * https://github.com/google/guava/blob/v20.0/guava/src/com/google/common/reflect/Invokable.java */ abstract class Invokable<T, R> : AccessibleObject(), Member, GenericDeclaration val <T : AccessibleObject> T.descriptor: Descriptor get() = when (this) { is Invokable<*, *> -> { val o = this // <---------------------------------CHANGES BEGIN FROM THIS LINE Descriptor(o.declaringClass, o.modifiers, info, o.declaringClass.info) } else -> throw AssertionError() }
这已经提交给JetBrains,但他们还没有回应,所以我会保持这个开放,直到他们证实或有人来嘲笑我的愚蠢。