2017-11-18 192 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。你可能會考慮是否使用它是一個選項。 –