kotlin - Kotlin:Enum 类上的通用接口,具有从 String 映射的静态方法
问题描述
假设我有很多枚举类,如下所示:
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) }
}
}
我希望能够创建一个通用接口来处理该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");
}
我试图将Kotlin 的答案合并为 enum class values method 定义接口,但看不到从接口中的伴随对象访问 enum values() 的方法。有没有一种干净的方法来做我想要的?
解决方案
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"))
}
推荐阅读
- sql - 根据 redshift 中另一列的值创建列
- php - Docker / PHP / Apache - 在容器内创建文件权限时丢失
- c++ - 使用 future<> 和 promise<> 进行消息传递?
- java - 此 URL 不支持 HTTP POST 方法:IntellJ IDEA JSP Servlet、DAO AND VO
- java - 在 Java 代码中使用的不易察觉的字符列表,以防止其被复制、粘贴和编译
- redis - Redis 过期复制到从站
- javascript - 引入 V8 后,Google Apps 脚本无法为其他用户完全执行
- build - 如何在 azure devops 管道中将项目文件复制到构建文件夹中?
- java - Hibernate 集合持久性
- ionic-framework - 如何使用带电容器的 Ionic Native 的 facebook auth