在Kotlin上铸造通用类型

Mon*_*chi 6 java generics casting kotlin

我试图让mapOf()返回EnumMap,如果K是Enum。但是,该错误发生在枚举(K)的第一个类型变量处

码:

@kotlin.internal.InlineOnly
public inline fun <reified K, V> mapOf(): Map<K, V> =
    if (K::class.java.isEnum) EnumMap<K, V>(K::class.java)
    else emptyMap()
Run Code Online (Sandbox Code Playgroud)

错误:

Type argument is not within its bounds.
Expected: Enum<K!>!
Found: K
Run Code Online (Sandbox Code Playgroud)

我也想给除Enum以外的对象,所以reified K: Enum<*>不能解决。

Jor*_*nee 3

没有干净的方法来完成这项工作(据我所知),因为要符合K绑定K extends Enum<K>(需要EnumMap)将需要动态添加绑定到K,这是不可能的,因为泛型是一种编译时机制。

在java中,您可以将 构造EnumMap为原始类型,并将其未经检查地转换为目标类型(即断言它是正确的)。但 Kotlin 不允许您这样做,因为它不允许原始类型。我可以想到一种方法来绕过这个限制,那就是反射:

val constructor = EnumMap::class.constructors.find {
    con ->
        con.parameters.size == 1
        && con.parameters[0].type.jvmErasure == Class::class
}!!

inline fun <reified K, V> mapOf(): Map<K, V> =
    if (K::class.java.isEnum) constructor.call(K::class.java) as Map<K, V>
    else emptyMap()
Run Code Online (Sandbox Code Playgroud)

我的 Kotlin 不是最好的,所以可能还有改进的空间。但这是一个可能的解决方法。