如何解决kotlin 中 Enum<T> 的函数可变参数
我有以下枚举,其中每个枚举类实现 RatingValue
接口,每个伴随对象实现 RatingValues<T>
接口
enum class Clarity(override val value: Int) : RatingValue {
EXCELENT(5),VERY_GOOD(4),GOOD(3),FAIR(2),POOR(1);
companion object : RatingValues<Clarity>
}
enum class Colour(override val value: Int) : RatingValue {
EXCELENT(10),VERY_GOOD(8),GOOD(6),FAIR(4),POOR(2);
companion object : RatingValues<Colour>
}
RatingValues
接口有 ratings()
方法,定义为扩展:
inline fun <reified T> RatingValues<T>.ratings(): List<Int> where T : RatingValue,T : Enum<T> = enumValues<T>().map { it.value }
我想实现一个方法,该方法采用 RatingValue
枚举的可变参数,可以像这样调用
val cumulativeRating = cumulate(Colour,Clarity)
我的第一个想法是编写以下内容,但是由于 RatingValues 的泛型类型参数 T 明显不同,因此失败了
private inline fun <reified T> cumulate(vararg ratings: RatingValues<T>) : List<Int> where T: RatingValue,T : Enum<T> {
return ratings
.map(RatingValues<T>::ratings)
.fold(listOf(0,0)) { x,y -> x.zip(y,Int::plus) }
}
解决方法
可以接受具有不同 RatingValues<T>
的可变参数 T
的方法是:
private fun cumulate(vararg ratings: RatingValues<*>): List<Int> {
return ratings
.map { it.ratings() }
.reduce { x,y -> x.zip(y,Int::plus) } //same semantics,but more concise and performant
}
问题是由于类型擦除,关于T
的实际类型的信息会丢失,所以它会被具体化为Object
,你会得到相当神秘的运行时错误:{{1 }}(在我看来,编译器不应该首先编译它,但这不是重点)。
恐怕,您必须将 java.lang.NoSuchMethodError: java.lang.Object.values()[Ljava/lang/Object;
接口中的 ratings()
方法定义为非泛型,并在每个枚举的伴随对象中实现它以使其正常工作:
RatingValues
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。