我认为这段代码应该编译:
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()
}
这是对Google Guava's Invokable的方便引用。简要Invokable
定义。
上面的代码应该编译所有正常但编译器产生3个奇怪的消息,这里是日志输出(经过适当的规范化):
e:/path/to/source.kt:(34,44):类型推断失败:val Invokable.declaringClass:Class! 无法应用 receiver:T#2(描述符的类型参数)参数:()
e:/path/to/source.kt:(35,44):类型推断失败:val Invokable.modifiers:Int 无法应用 receiver:T#2(描述符的类型参数)参数:()
e:/path/to/source.kt:(37,44):类型推断失败:val Invokable.declaringClass:Class! 无法应用 receiver: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()
}
这已经是submitted to JetBrains,但他们还没有做出回应,所以我会保持这种状态,直到他们验证或有人上骂我的愚蠢。
答案 0 :(得分:0)
智能演员似乎不够聪明。但是您可以使用以下方法给出提示:
val <T : AccessibleObject> T.descriptor: Descriptor
get() = when (this) {
is Invokable<*, *> -> {
Descriptor(this.declaringClass,
this.modifiers,
info,
this.declaringClass.info)
}
else -> throw AssertionError()
}
无需使用val的东西。你只需要给它&#34;东西&#34;继续努力。当没有任何东西可以使它变得凌乱时,可以突出显示&#34;在IDE上:)