Kotlin 枚举的函数vararg参数<;T>;在科特林

Kotlin 枚举的函数vararg参数<;T>;在科特林,kotlin,generics,enums,variadic-functions,Kotlin,Generics,Enums,Variadic Functions,我有以下枚举,其中每个枚举类实现RatingValue接口,每个伴随对象实现RatingValue接口 enum类清晰度(覆盖值:Int):分级值{ 卓越(5), 非常好(4), 好(三),, 公平(2), 差(1); 伴生对象:额定值 } 枚举类颜色(覆盖值:Int):额定值{ 卓越(10), 非常好(8), 好(六),, 公平(4), 差(2); 伴生对象:额定值 } RatingValues接口具有ratings()方法,该方法定义为扩展: inline fun RatingValues

我有以下枚举,其中每个枚举类实现
RatingValue
接口,每个伴随对象实现
RatingValue
接口

enum类清晰度(覆盖值:Int):分级值{
卓越(5),
非常好(4),
好(三),,
公平(2),
差(1);
伴生对象:额定值
}
枚举类颜色(覆盖值:Int):额定值{
卓越(10),
非常好(8),
好(六),,
公平(4),
差(2);
伴生对象:额定值
}
RatingValues
接口具有
ratings()
方法,该方法定义为扩展:

inline fun RatingValues.ratings():列出其中T:RatingValue,T:Enum=enumValues().map{it.value}
我想实现一个方法,该方法采用
RatingValue
enums的vararg参数,该参数可以这样调用

val cumulative=cumulative(颜色、清晰度)
我的第一个想法是编写以下内容,但是由于RatingValues的泛型类型参数T明显不同,因此这一点失败了

private-inline-fun累积(vararg ratings:RatingValues):列出其中T:RatingValue,T:Enum{
回报率
.map(额定值::额定值)
.fold(listOf(0,0,0,0,0)){x,y->x.zip(y,Int::plus)}
}

可以接受不同
T
的vararg
额定值的方法是:

private fun cumulate(vararg评级:评级值):列表{
回报率
.map{it.ratings()}
.reduce{x,y->x.zip(y,Int::plus)}//相同的语义,但更简洁、更高效
}
问题是,由于类型擦除,关于
T
的实际类型的信息将丢失,因此它将被具体化为
Object
,并且您将得到相当隐晦的运行时错误:
java.lang.NoSuchMethodError:java.lang.Object.values()[Ljava/lang/Object;
(在我看来,编译器本来不应该编译这个,但这不是重点)

恐怕您必须在
RatingValues
接口中将
ratings()
方法定义为非泛型方法,并在每个枚举的伴生对象中实现它,以使其正常工作:

接口额定值,其中T:RatingValue,T:Enum{
趣味分级():列表
}
内联fun RatingValues.ratingsForEnums():列表,其中T:RatingValue,T:Enum=
enumValues().map{it.value}
枚举类清晰度(覆盖值:Int):分级值{
卓越(5),
非常好(4),
好(三),,
公平(2),
差(1);
伴生对象:额定值{
覆盖趣味分级()=分级福利()
}
}
枚举类颜色(覆盖值:Int):额定值{
卓越(10),
非常好(8),
好(六),,
公平(4),
差(2);
伴生对象:额定值{
覆盖趣味分级()=分级福利()
}
}

可以接受不同
T
的vararg
额定值的方法是:

private fun cumulate(vararg评级:评级值):列表{
回报率
.map{it.ratings()}
.reduce{x,y->x.zip(y,Int::plus)}//相同的语义,但更简洁、更高效
}
问题是,由于类型擦除,关于
T
的实际类型的信息将丢失,因此它将被具体化为
Object
,并且您将得到相当隐晦的运行时错误:
java.lang.NoSuchMethodError:java.lang.Object.values()[Ljava/lang/Object;
(在我看来,编译器本来不应该编译这个,但这不是重点)

恐怕您必须在
RatingValues
接口中将
ratings()
方法定义为非泛型方法,并在每个枚举的伴生对象中实现它,以使其正常工作:

接口额定值,其中T:RatingValue,T:Enum{
趣味分级():列表
}
内联fun RatingValues.ratingsForEnums():列表,其中T:RatingValue,T:Enum=
enumValues().map{it.value}
枚举类清晰度(覆盖值:Int):分级值{
卓越(5),
非常好(4),
好(三),,
公平(2),
差(1);
伴生对象:额定值{
覆盖趣味分级()=分级福利()
}
}
枚举类颜色(覆盖值:Int):额定值{
卓越(10),
非常好(8),
好(六),,
公平(4),
差(2);
伴生对象:额定值{
覆盖趣味分级()=分级福利()
}
}

感谢您的详细解释。我认为在这种情况下,我会坚持将实际评级列表作为参数传递给
累积
,因为我希望保持枚举定义的干净(实际上还有很多这样的枚举)。但是,这几乎证实了我对为什么不可能的怀疑。感谢您的详细解释。我认为在这种情况下,我宁愿将实际评级列表作为参数传递给
累积
,因为我希望保持枚举定义的干净性(实际上还有很多这样的枚举).然而,这几乎证实了我对为什么不可能的怀疑。