超出预期的类型...禁止使用FooTable中定义的'public open fun ....

时间:2018-10-05 02:21:29

标签: kotlin

我有以下课程:

abstract class FooTable<M, D> where M : IModel, D : IDto {

    ///...

    fun getTableData(models: ArrayList<M>): ArrayList<D> {
        // ...
    }

}

我还有另一个使用它的类,例如:

abstract class FooPage<M, F> where M : IModel, F : IFilter {
    abstract val table: FooTable<M, out IDto>

然后在我的代码中尝试执行的操作:

page.table.getTableData(arrayListOf(m1, m2)).first()

它给了我

  

投影类型FooTable<out IModel, out IDto>禁止使用public final fun getTableData(models: kotlin.collections.ArrayList<M> /* = java.util.ArrayList<M> */): kotlin.collections.ArrayList<D> /* = java.util.ArrayList<D> */中定义的com.menighin.example.models.FooTable

以下是有关该问题的小提琴:https://pl.kotl.in/ryirJJH9m

代码是:

interface IModel

interface IDto

interface IFilter

class Model : IModel

class Dto : IDto

class Filter : IFilter

class FooTable<M, D> where M : IModel, D : IDto {
    fun getTableData(models: List<M>): ArrayList<D> {
        return ArrayList()
    }

    fun testPage(masterModel: IModel, thisPage: FooPage<out IModel, out IFilter>) {
        thisPage.table.getTableData(arrayListOf(masterModel)) // Error here
    }

    fun testTable(masterModel: IModel, masterTable: FooTable<out IModel, out IDto>) {
        masterTable.getTableData(arrayListOf(masterModel)) // And error here
    }
}

class FooPage<M, F> where M : IModel, F : IFilter {
    val table: FooTable<M, out IDto> = FooTable()
}


fun main() {

    val page = FooPage<Model, Filter>()

    val a = page.table.getTableData(arrayListOf())

    println("Hello, world!!!")
}

基本上,我的FooTable中有一个函数,我需要在其中获取另一个表的引用并获取其数据。我想我已经可以传递数据了,但是我很想知道为什么现在不起作用...

我从this question那里了解到,如果我可以将abstract val table: FooTable<M, out IDto>更改为abstract val table: FooTable<M, Any>,那是可以的...但是,据我所知,我不能,因为FooTable对于实现IDto的第二个参数非常严格。

我该如何解决?

1 个答案:

答案 0 :(得分:0)

问题在于,在您的testTable函数中,您指定masterTable的第一个通用类型限制(IModel)是out。如果将声明更改为此,它将编译:

fun testTable(masterModel: IModel, masterTable: FooTable<in IModel, out IDto>)

(或者,既不指定in也不指定out。)

here对此进行了解释(尽管确实需要花一些时间才能理解)。我认为您现有的代码(具有IModel的{​​{1}}泛型类型限制)指出out参数产生masterTable s,但是没有关于接收的规则因此,错误(至少在IntelliJ中)为:

类型不匹配。必填IModel。找到了List<Nothing>

由于编译器不知道List<IModel>可以接受什么,因此无法确定它是否可以接受您试图传递给masterTable的{​​{1}}方法。