[英]Implement abstract class with constrained generic in Kotlin
在 Kotlin 1.3.61 上工作
有這個代碼:
abstract class ResourceObserver<T> : Observer<T> where T : Resource<T> {
override fun onChanged(t: T) {
when (t.status) {
Status.LOADING -> { ... }
Status.ERROR -> { ... }
Status.SUCCESS -> { onSuccess(t.data) }
}
}
abstract fun onSuccess(data: T?)
}
並嘗試實施它
private val foo = object : ResourceObserver<Resource<Bar>> {
override fun onSuccess(data: Bar?) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
}
編譯器(在本例中為 Android Studio)給我這個錯誤:
Type argument is not within its bounds.
Expected: Resource<Resource<Bar>>
Found: Resource<Bar>
我明顯錯誤的代碼有什么問題?
where T: Resource<T>
的約束確實要求您為T
使用的任何類型參數也必須是Resource<T>
( T
由類型本身替換)。
根據此約束,您為實現T:= Resource<Bar>
提供的類型參數將被檢查為Resource<T> ≡ Resource<Resource<Bar>>
並且未通過此檢查。
要使此約束和子類型起作用, Bar
需要是Resource<Bar>
的子類型(實現)。
您真的需要T
成為具有相同T
的Reosurce<T>
嗎? 如果您使用帶星投影的上限T: Resource<*>
或添加另一個類型參數,它會解決您的問題嗎,如下所示?
abstract class ResourceObserver<T, R> : Observer<T> where T : Resource<R> { ... }
private val foo = object : ResourceObserver<Resource<Bar>, Bar> { ... }
這看起來像是在嘗試使用F-bounded polymorphism 。 為了讓它工作,你需要
使Bar
擴展Resource<Bar>
;
制作private val foo = object: ResourceObserver<Bar> {... }
而不是<Resource<Bar>>
。
通常Resource
本身將被聲明為具有類似的約束
class Resource<T : Resource<T>>
所以如果你忘記做 1 Bar
將無法編譯。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.