我有这样的事情:
import kotlin.reflect.KClass
class Quantity<T> {
/* ... */
}
class Field<T : Any> {
val type: KClass<T> get() = TODO("This is initialized, don't worry about implentation details, just know that fields know their type.")
fun initValue(value: T) {
/* Do something very useful */
}
/* Other methods */
class Template<T : Any> {
fun initFieldWithValue(value: T): Field<T> {
return Field<T>().apply {
this.initValue(value)
}
}
}
}
class ComponentClass(
val fieldsTemplates: Map<String, Field.Template<*>>
) {
inner class Instance(field: Map<String, Field<*>>)
fun new(fieldValues: Map<String, Quantity<*>>): Instance {
val fields = mutableMapOf<String, Field<*>>()
for ((fieldName, template) in fieldsTemplates) {
fields[fieldName] = fieldsTemplates
.getValue(fieldName)
.initFieldWithValue(fieldValues.getValue(fieldName) /* Here a type error */)
}
return Instance(fields)
}
}正如您可能猜到的那样,这是作为一种“运行时方式”来创建属于自己的字段的类(Field<T>类),每个类都具有一个类型化值(由Quantity<T>表示)。
问题是,这段代码无法编译,因为在创建未来的fieldValues方法中的Instance的不同字段时,从new中检索的数量不能保证是填充到的字段所需的类型。
问题是,我需要检查,因为用Field<Quantity<String>>填充Quantity<Int>显然不是一个好主意,但是由于类型擦除,我无法确保传入的数量是好类型。
知道吗?还有一个想法:Field知道它们的类型是什么,这要归功于它们的type属性,但不幸的是,我不能对Quantity类做同样的事情.
发布于 2022-01-20 22:36:35
您的initFieldWithValue函数强制执行参数的类型,以匹配模板/字段已知的类型。但是在您的new函数中,模板是一个Template<*>,因为您从一个集合中检索它,其中的值就是这种类型。
泛型的目的是加强编译时间检查,以便在引擎盖下安全和自动地进行转换。这只有在编译时知道您的类型时才有用。在这种情况下,在编译时不知道类型,所以泛型会阻止代码编译。这就是泛型应该做的事情:如果编译器不能检查它们的类型是否匹配,就阻止代码编译。
如果希望编译此代码,则应更改initFieldWithValue,使其不强制使用泛型。您可以手动检查类型,如果错误,可以抛出错误或提前退出。这将取决于您的代码在其他地方,以确保您没有混合和匹配类型。
下面是一个可以工作的版本的示例。它的类型检查需要Kotlin反射库。如果您只针对JVM,则可以使用Java方法来进行此检查。
class Template<T : Any> {
val type: KClass<T> get() = TODO()
/**
* @throws IllegalStateException if [value] is not of the same type
* as this Template's [type].
*/
fun initFieldWithValue(value: Any): Field<T> {
if (!value::class.isSubclassOf(type)) {
error("Invalid value type for Field type of $type")
}
return Field<T>().apply {
@Suppress("UNCHECKED_CAST") // we manually checked it above
initValue(value as T)
}
}
}https://stackoverflow.com/questions/70793469
复制相似问题