假设我有许多枚举类,如下所示:
enum class Hero(val alias: String) {
SUPERMAN("Clark Kent"),
BATMAN("Bruce Wayne");
companion object {
fun fromAlias(value: String): Hero? = Hero.values().find { it.alias.equals(value, true) }
}
}
enum class Villain(val alias: String) {
TWO_FACE("Harvey Dent"),
RIDDLER("Edward Nigma");
companion object {
fun fromAlias(value: String): Villain? = Villain.values().find { it.alias.equals(value, true) }
}
}
Run Code Online (Sandbox Code Playgroud)
我希望能够创建一个通用接口来处理该fromAlias
方法,以便我仍然可以使用Hero.fromAlias("Bruce Wayne")
. 所以我的枚举类将被简化为:
enum class Hero(override val alias: String): AliasedEnum<Hero> {
SUPERMAN("Clark Kent"),
BATMAN("Bruce Wayne");
}
enum class Villain(override val alias: String): AliasedEnum<Villain> {
TWO_FACE("Harvey Dent"),
RIDDLER("Edward Nigma");
}
Run Code Online (Sandbox Code Playgroud)
我尝试合并Kotlin Define interface for enum class values method 的答案,但找不到从接口中的伴随对象访问枚举 value() 的方法。有没有一种干净的方法来做我想要的事情?
通过companion object
对象可以扩展其他类这一事实,您可以很容易地做到这一点。
几乎任何解决方案都需要两个不同的部分,因为您需要:
companion object
访问的方法<Class>.function
。这可以是具有所需实现的抽象类,也可以是具有作为扩展函数的实现的标记类。最后“最干净”的解决方案可能是这样的:
// Attaching point for the extension function which provides the answer
interface EnumCompanion<T : Enum<T>>
// Marker interface to provide the common data
interface WithAlias {
val alias: String
}
inline fun <reified T> EnumCompanion<T>.fromAlias(
value: String
): T? where T : Enum<T>, T : WithAlias {
return enumValues<T>().find { it.alias == value }
}
// Define the enums and attach the helper to their companion object
enum class Hero(override val alias: String) : WithAlias {
SUPERMAN("Clark Kent"),
BATMAN("Bruce Wayne");
companion object : EnumCompanion<Hero>
}
enum class Villain(override val alias: String) : WithAlias {
TWO_FACE("Harvey Dent"),
RIDDLER("Edward Nigma");
companion object : EnumCompanion<Villain>
}
fun main() {
println(Hero.fromAlias("Bruce Wayne"))
println(Villain.fromAlias("Edward Nigma"))
}
Run Code Online (Sandbox Code Playgroud)