尝试为包装另一个泛型类型的类型实现泛型初始值设定项。
具有用于通用枚举类型的反向映射器
class SerializableEnumMapper<V, T>(
enumValues: Array<T>
) where T : Enum<T>, T: SerializableEnum<V> {
private val mapEnum: Map<V, T> =
mutableMapOf<V, T>().apply {
enumValues.forEach {
this[it.rawValue] = it
}
}
fun getEnum(value: V): T? = mapEnum[value]
}
其中 SerializableEnum
是提供原始值的通用接口。
interface SerializableEnum<T> {
val rawValue: T
}
现在,对于以下枚举:
enum class SomeEnum(
override val rawValue: Int
): SerializableEnum<Int> {
THIRTY_SEVEN(37),
FORTY_TWO(42)
}
我可以简单地通过以下方式创建映射器:
val someEnumMapper = SerializableEnumMapper(SomeEnum.values()) // Works fine
但只是为了为此提供一个更通用的初始化器,我想要这样的东西:
val anotherEnumMapper = enumMapperOf<SomeEnum>() // How to do this one?
我最接近这个的:
val anotherEnumMapper = enumMapperOf<Int, SomeEnum>() // Still need to provide Int here :(
inline fun <V, reified T> enumMapperOf() where T : Enum<T>, T: SerializableEnum<V> =
SerializableEnumMapper(enumValues<T>())
有没有办法以我们只需要提供 Enum
类型并且可以隐式引用底层 Int
类型的方式编写?
答案 0 :(得分:2)
enumMapperOf
的返回类型是 SerializableEnumMapper<V, T>
。它有两个泛型类型参数。尽管它们是相关的,但您不能将返回类型声明为 SerializableEnumMapper<T.T, T>
(我认为这就是您要问的?),因为这不是一回事。 (不过这在其他语言中是一回事。)您确实需要两个类型参数,并将它们与此处的约束联系起来。
但是,如果您对使用另一种语法感到满意,则可以改用它:
val anotherEnumMapper = enumMapperOf(SomeEnum::class)
inline fun <V, reified T> enumMapperOf(clazz: KClass<T>) where T : Enum<T>, T: SerializableEnum<V> =
SerializableEnumMapper(enumValues<T>())
这允许您避免编写 Int
,但引入了一个“无用”参数 - 它仅用于推断两个通用参数。