Kotlin 中抽象容器工具的泛型 in/out?
Generics in/out for abstract container tool in Kotlin?
我正在创建一个抽象工具 class,它在另一组外国 classes(不受我控制)上运行。外来的 classes 在某些接口点上在概念上是相似的,但在访问它们相似的属性时具有不同的语法。它们还具有不同的语法来应用工具的操作结果。我创建了一个数据 class,内部 classes,基于 .
这是泛型问题: 外来的 classes 基本上是元素的容器。每个 class' 容器类型都不同。某些容器具有固定的元素类型,而其他容器则具有通用元素类型。我无法将 in
与 out
、协变与逆变的泛型概念应用于此模型。下面是一个使用 CharSequence 和 List 切片的简化示例,它与泛型方面的问题几乎完全相似:
// *** DOES NOT COMPILE ***
data class Slicer<C,E>(val obj: C, val beg: Int, val end: Int) {
// C is container type; E is element type
// but unsure how to apply in/out properly
inner abstract class SObj<C,E>{
abstract val len: Int // an input that tool requires
abstract val sub: C // an output of tool (container)
abstract val one: E // an output of tool (element)
inner class TCsq(val c: CharSequence): SObj<C,E>() {
override val len get()= c.length
override val sub get()= c.substring(adjusted) // PROBLEM
override val one get()= c[finder+5] // PROBLEM
}
inner class TList<E>(val l: List<E>): SObj<C,E>() {
override val len get()= l.size
override val sub get()= l.slice(adjusted) // PROBLEM
override val one get()= l[finder] // PROBLEM
}
// sample ops use both data class vals and abstract properties
val adjusted get()= (beg+1)..(len-1)
val finder get()= (end-beg)/2
}
}
我如何在此处正确应用 in/out 来完成这项工作? 或者,如果这不是最好的构造,那么它还可以如何构造?
N.B。请记住,CharSequence
和 List
表示无法修改的外部 classes,而 adjusted
和 finder
是该工具的许多操作的示例在 classes 上表演。今天,该工具的操作只是以重复和不统一的方式散布在各种容器内(或扩展)的代码库中。
如果我理解正确的话,方差在这里不相关,你只是把参数弄错了:
inner class TCsq(val c: CharSequence): SObj<CharSequence, Char>()
和
inner class TList<E>(val l: List<E>): SObj<List<E>,E>()
您不能用这种方式进行的操作是"change E
":这需要 Kotlin 不支持的更高种类的类型。
我正在创建一个抽象工具 class,它在另一组外国 classes(不受我控制)上运行。外来的 classes 在某些接口点上在概念上是相似的,但在访问它们相似的属性时具有不同的语法。它们还具有不同的语法来应用工具的操作结果。我创建了一个数据 class,内部 classes,基于
这是泛型问题: 外来的 classes 基本上是元素的容器。每个 class' 容器类型都不同。某些容器具有固定的元素类型,而其他容器则具有通用元素类型。我无法将 in
与 out
、协变与逆变的泛型概念应用于此模型。下面是一个使用 CharSequence 和 List 切片的简化示例,它与泛型方面的问题几乎完全相似:
// *** DOES NOT COMPILE ***
data class Slicer<C,E>(val obj: C, val beg: Int, val end: Int) {
// C is container type; E is element type
// but unsure how to apply in/out properly
inner abstract class SObj<C,E>{
abstract val len: Int // an input that tool requires
abstract val sub: C // an output of tool (container)
abstract val one: E // an output of tool (element)
inner class TCsq(val c: CharSequence): SObj<C,E>() {
override val len get()= c.length
override val sub get()= c.substring(adjusted) // PROBLEM
override val one get()= c[finder+5] // PROBLEM
}
inner class TList<E>(val l: List<E>): SObj<C,E>() {
override val len get()= l.size
override val sub get()= l.slice(adjusted) // PROBLEM
override val one get()= l[finder] // PROBLEM
}
// sample ops use both data class vals and abstract properties
val adjusted get()= (beg+1)..(len-1)
val finder get()= (end-beg)/2
}
}
我如何在此处正确应用 in/out 来完成这项工作? 或者,如果这不是最好的构造,那么它还可以如何构造?
N.B。请记住,CharSequence
和 List
表示无法修改的外部 classes,而 adjusted
和 finder
是该工具的许多操作的示例在 classes 上表演。今天,该工具的操作只是以重复和不统一的方式散布在各种容器内(或扩展)的代码库中。
如果我理解正确的话,方差在这里不相关,你只是把参数弄错了:
inner class TCsq(val c: CharSequence): SObj<CharSequence, Char>()
和
inner class TList<E>(val l: List<E>): SObj<List<E>,E>()
您不能用这种方式进行的操作是"change E
":这需要 Kotlin 不支持的更高种类的类型。