我是相對較新的 Kotlin 和泛型有點讓我頭疼。我有以下架構:
- 一些資料類
- 處理資料的通用介面
- 每種資料型別的處理介面的實作
- 包含要處理的資料及其適當處理器的通用處理作業類
- 實作處理介面的全域(單例)處理器,接受處理作業并將處理委托給作業處理器。它根本不關心資料本身。
簡化的代碼如下所示
class DataOne
class DataTwo
interface DataProcessor<in T> {
fun process(o: T)
}
class DataOneProcessor: DataProcessor<DataOne> {
override fun process(o: DataOne) = println("Processing DataOne")
}
class DataTwoProcessor: DataProcessor<DataTwo> {
override fun process(o: DataTwo) = println("Processing DataTwo")
}
class ProcessingJob<T>(val data: T, val processor: DataProcessor<T>)
object GlobalProcessor: DataProcessor<ProcessingJob<Any>> {
override fun process(job: ProcessingJob<Any>) = job.processor.process(job.data)
}
fun main() {
GlobalProcessor.process(ProcessingJob(DataOne(), DataOneProcessor()))
}
在主函式中,我得到一個編譯器錯誤
Type mismatch.
Required: ProcessingJob<Any>
Found: ProcessingJob<DataOne>
我理解為什么會發生這種情況: A DataProcessorof DataOne,被視為 a DataProcessorofAny可以被要求處理DataTwos 并且為了型別安全,這是不允許的。
你能給我任何關于如何/改變什么以使其編譯并達到所需結果的建議嗎?謝謝你的時間!
uj5u.com熱心網友回復:
這里有兩個問題。
首先,Any實際上不是頂級型別。Any意味著不T為空,但不受約束,這意味著它可以是可為空的型別。在這種情況下,您可以使用*,也可以將型別指定為Any?。
將簽名更改為GlobalProcessor:
object GlobalProcessor: DataProcessor<ProcessingJob<*>> {
override fun process(job: ProcessingJob<*>): ...
第二個問題是實作process不能利用來自the的通用資訊job來知道thejob.processor和thejob.data是兼容的。它只看到兩個未知型別的物件。要讓它知道它們共享一個兼容型別,您需要將該型別捕獲為型別變數。我們不能在現有方法中添加泛型型別引數,因為它必須匹配介面方法的簽名,但是我們可以添加一個引入泛型引數的新私有方法。
這GlobalProcessor是所需的更改。
object GlobalProcessor: DataProcessor<ProcessingJob<*>> {
override fun process(job: ProcessingJob<*>) = processGeneric(job)
private fun <T> processGeneric(job: ProcessingJob<T>) = job.processor.process(job.data)
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/516366.html
標籤:科特林仿制药
下一篇:具有鍵更改的陣列中的映射型別
