2017-11-18 242 views
1

我正在创建一个抽象工具类,对另一组外部类(不受我控制)进行操作。外部类在概念上在界面的某些点上是相似的,但是对于访问它们的类似属性有不同的语法。他们对应用工具操作的结果也有不同的语法。我已经创建了一个带有内部类的数据类,基于this answer by @hotkeyKotlin中的抽象容器工具的泛型输入/输出?

这里是仿制药问题:外国类基本上是元素的容器。每个班级的容器类型是不同的。某些容器具有固定的元素类型,而其他容器具有通用元素类型。我无法应用inout的泛型概念,协方差与此模型的逆变。下面是使用CharSequence的切片,并列出几乎完全平行的问题,相对于仿制药简化的例子:

// *** 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 
    } 
} 

如何正确地应用在/在这里,使这项工作?或者,如果这不是最好的构造,那么这个构造还可以如何呢?

N.B.请记住,CharSequenceList代表无法修改的外部类,而adjustedfinder是工具在类上执行的许多操作的示例。今天,工具的操作只是以重复和非均匀的方式散布在各个容器内的代码库(或作为其扩展)。

回答

1

如果我理解正确的问题,方差是不是与此有关,你只是得到的参数错误:

inner class TCsq(val c: CharSequence): SObj<CharSequence, Char>() 

inner class TList<E>(val l: List<E>): SObj<List<E>,E>() 

不能做些什么这样将有“改变E”的操作:这需要Kotlin不支持的更高级的类型。

+0

看起来像我的问题是两个都有点。当我简化了您修正的代码时,我犯了一个错误。但是,正如你所预测的那样,一些真实代码试图“改变E”。 (我真的应该把其中的一个放在我的例子中,但是你没有看到这个例子就知道了。)我试图在容器类型中尝试'in'和'out'的不同组合来实现这一点,但是现在我意识到这些都不起作用,因为这实际上比这些仿制药的订单要高。 – sirksel

+0

很少有支持这种语言的语言,但实际上JVM上有一个:Scala。你可能会考虑是否使用它是一个选项。 –