为什么编译器在父构造函数中不理解泛型父类型

路易斯·萨利奥

以下代码片段无法编译(Kotlin 1.7.0),因为在PFrag调用它的父 ( Frag) 构造函数时,V它不被识别为ViewModel<PRepo>.
但是我认为它应该是因为V类型是PViewModel<M, R>作为PViewModel孩子的孩子ViewModelR孩子的孩子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>()
清扫车

让我们分解一下:

  • 为了Frag<PRepo, V>工作,它必须是这样的V : ViewModel<PRepo>,根据 中的约束Frag

  • 我们知道V: PViewModel<M, R>,也PViewModel<M, R>: ViewModel<R>从他们各自的声明中知道

  • 所以,V: ViewModel<R>

  • 即使R: PRepoV: 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

  • 或者,将基类更改PFragFrag<R, V>所需V : ViewModel<R>的,而不是V : ViewModel<PRepo>

    abstract class PFrag<M: PModel, R: PRepo, V: PViewModel<M, R>>: Frag<R, V>()
    

哪种方式最适合取决于您的情况。如果没有关于这些类型代表什么的更多信息,我无法判断,尽管我认为更改基类很可能是您想要的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么Java编译器失去构造函数实例化轨道泛型类型的?

为什么Java编译器不理解此变量总是初始化的?

编译器无法推断泛型类构造函数类型的原因是什么?

不理解 F# 中的泛型

为什么父类的泛型类型在子类中忽略?

为什么不理解该解释器变量?

通过AJAX将变量传递给PHP函数变得不确定,但不理解为什么构造中缺少索引

为什么编译器不对扩展接口的泛型强制执行返回类型值?

为什么编译器不推断泛型

解决泛型类型约束中的编译器错误

泛型类构造函数获取父级,在父级中设置值?

为什么反引号构造函数参数中的空格会破坏编译器?

为什么编译器不能匹配此函数类型?

为什么在父类中调用了错误的构造函数?

为什么Flow不理解`export default`

为什么调用父的构造函数

为什么C#编译器强制在构造函数中显式初始化所有值类型的字段?

张量流中不理解的数据类型

我不理解Python中的用户定义函数

为什么这个java接口定义使用编译器接受的泛型?

为什么编译器声称泛型即使应有也不实现`Display`?

Java-本地类和泛型,为什么会出现编译器警告?

为什么编译器可以与未关闭的泛型一起使用?

为什么运算符<对于Java泛型有编译器错误?

为什么编译器不允许从 peek 方法返回的泛型不是可选的?

编译器如何推断泛型方法的类型?

声明泛型类型时的编译器警告

不理解python中的列表理解

为什么编译器在具有双界泛型类型时不将 T(interface) 推断为实现 T 的类?