You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 18:27:07