如何在Kotlin中创建以特定枚举为参数的Int泛型扩展函数
Kotlin Int转指定枚举List扩展函数实现
推荐实现(无反射,性能最优)
这种方式需要先定义通用接口约束枚举的Int属性,避免反射开销:
// 定义通用Int枚举接口 interface IntValuedEnum { val intValue: Int } // 扩展函数实现,用reified具体化泛型类型 inline fun <reified E> Int.toEnumList(): List<E> where E : Enum<E>, E : IntValuedEnum { // 获取所有枚举实例,过滤intValue小于等于当前Int值的项 return enumValues<E>().filter { it.intValue <= this } }
对应的枚举类需要实现上述接口:
enum class Animal(override val intValue: Int) : IntValuedEnum { CAT(15), BIRD(8), HAMSTER(4) }
调用方式(必须显式指定泛型参数,Kotlin无法自动推断枚举类型):
val filteredAnimals = 8.toEnumList<Animal>() // 输出:[BIRD, HAMSTER]
可选实现(反射方案,无需修改枚举类)
如果你不想改动现有枚举类的定义,可以用反射读取枚举的第一个Int类型构造参数值:
import kotlin.reflect.full.primaryConstructor inline fun <reified E : Enum<E>> Int.toEnumList(): List<E> { val enumEntries = enumValues<E>() // 读取枚举主构造器的第一个Int参数对应的属性值 val intParamGetter = E::class.primaryConstructor!!.parameters.first { it.type.classifier == Int::class } .let { param -> { e: E -> E::class.members.first { it.name == param.name }.call(e) as Int } } return enumEntries.filter { intParamGetter(it) <= this } }
这种方式的枚举类不需要额外实现接口,直接用原有定义即可:
enum class Animal(val maxAge: Int) { CAT(15), BIRD(8), HAMSTER(4) }
调用方式和上面一致:
val filteredAnimals = 8.toEnumList<Animal>()
核心说明
原设想代码无法直接运行的核心原因是未具体化泛型,JVM运行时会擦除泛型信息,不知道E的具体类型,无法调用对应方法获取枚举实例。reified+inline的组合可以绕过JVM泛型擦除限制,在运行时拿到枚举的实际类型信息。
内容的提问来源于stack exchange,提问作者alandyalbeardness
相关产品推荐
相关产品推荐

