以下代碼片段無法編譯(Kotlin 1.7.0),因為在PFrag呼叫它的父 ( Frag) 建構式時,V它不被識別為ViewModel<PRepo>.
但是我認為它應該是因為V型別是PViewModel<M, R>作為PViewModel孩子的孩子ViewModel和R孩子的孩子PRepo。
是否可以稍微修改此代碼以使其編譯(可能使用out關鍵字)?還是因為一些我還沒有看到的問題而不可能?
interface Model
abstract class Repo
abstract class ViewModel<R: Repo>
abstract class Frag<R: Repo, V: ViewModel<R>>
interface PModel: Model
abstract class PRepo: Repo()
abstract class PViewModel<M: PModel, R: PRepo>: ViewModel<R>()
abstract class PFrag<M: PModel, R: PRepo, V: PViewModel<M, R>>: Frag<PRepo, V>()
uj5u.com熱心網友回復:
讓我們分解一下:
為了
Frag<PRepo, V>作業,它必須是這樣的V : ViewModel<PRepo>,根據 中的約束Frag。我們知道
V: PViewModel<M, R>,也PViewModel<M, R>: ViewModel<R>從他們各自的宣告中知道所以,
V: ViewModel<R>即使
R: PRepo,V: ViewModel<R>并不意味著V: ViewModel<PRepo>。為此,R需要標記為out:abstract class ViewModel<out R: Repo>這可以防止您在輸入位置中
ViewModel寫入任何方法/屬性。R你也可以這樣做:abstract class Frag<R: Repo, V: ViewModel<out R>>這會阻止您使用處于輸入位置的
V任何成員。R或者,將基類更改
PFrag為Frag<R, V>所需V : ViewModel<R>的,而不是V : ViewModel<PRepo>:abstract class PFrag<M: PModel, R: PRepo, V: PViewModel<M, R>>: Frag<R, V>()
哪種方式最適合取決于您的情況。如果沒有關于這些型別代表什么的更多資訊,我無法判斷,盡管我認為更改基類很可能是您想要的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/494532.html
下一篇:迭代列舉引數的型別
