如何通过枚举值关联类型/类,简化Kotlin泛型重复代码?
简化Kotlin枚举关联泛型的when语句方案
你遇到的核心问题是:泛型参数是编译期确定的类型,而枚举里存储的Class对象是运行时实例,没法直接用它填充尖括号里的泛型参数。要简化重复的when分支,我们可以给枚举添加泛型绑定,把每个类型对应的解析、保存逻辑封装到枚举值里。
第一步:修改枚举定义,绑定泛型与保存逻辑
给枚举添加泛型参数,同时让每个枚举值携带对应的实体类Class,以及该类型数据的保存逻辑(直接引用对应的Repository):
enum class SnowflakeDataType<T>( val clazz: Class<T>, private val saveAction: (List<T>) -> Unit ) { SNOWFLAKE_RESERVE_BOOKING( SnowflakeReserveItem::class.java, { snowflakeItemRepository.saveAll(it) } ), SNOWFLAKE_MEMBERSHIP_TERM( SnowflakeMembershipTerm::class.java, { snowflakeMembershipTermRepository.saveAll(it) } ), SNOWFLAKE_MEMBERSHIP_BOOKING( SnowflakeMembershipOrderBooking::class.java, { snowflakeMembershipItemRepository.saveAll(it) } ), SNOWFLAKE_OFFLINE_SALE_BOOKING( SnowflakeOfflineItem::class.java, { snowflakeOfflineItemRepository.saveAll(it) } ), SNOWFLAKE_ONLINE_SALE_BOOKING( SnowflakeOnlineItem::class.java, { snowflakeOnlineItemRepository.saveAll(it) } ); // 对外暴露保存方法 fun save(items: List<T>) = saveAction(items) }
第二步:简化persistSnowflakeData函数
利用枚举的泛型绑定,只需要一段通用逻辑就能处理所有类型:
fun persistSnowflakeData(inputStream: InputStream, dataType: SnowflakeDataType<*>) { // 强制转换是安全的,因为每个枚举值的泛型参数与clazz、saveAction完全匹配 @Suppress("UNCHECKED_CAST") val typedDataType = dataType as SnowflakeDataType<Any> val sfItems = GenericCsvParser<Any>() .parse(inputStream, typedDataType.clazz) .toList() typedDataType.save(sfItems) }
为什么这么做能解决问题?
原来的重复when分支本质是在手动匹配「枚举值-实体类型-Repository」的关联,现在我们把这层关联直接封装到枚举定义里:
- 枚举的泛型参数
<T>让每个枚举值在编译期就明确对应的实体类型,解决了泛型参数无法动态指定的问题; - 把Repository的保存逻辑作为lambda传入枚举,让每个枚举值自己知道如何处理数据保存,避免了分支里的重复代码。
内容的提问来源于stack exchange,提问作者Eogcloud
相关产品推荐
相关产品推荐

