【问题标题】:Out-projected type ... prohibits the use of 'public open fun .... defined in FooTableOut-projected type ...禁止使用'public open fun ....在FooTable中定义
【发布时间】:2018-10-05 02:21:29
【问题描述】:

我有以下课程:

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&lt;out IModel, out IDto&gt;禁止使用com.menighin.example.models.FooTable中定义的public final fun getTableData(models: kotlin.collections.ArrayList&lt;M&gt; /* = java.util.ArrayList&lt;M&gt; */): kotlin.collections.ArrayList&lt;D&gt; /* = java.util.ArrayList&lt;D&gt; */

这是一个问题: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&lt;M, out IDto&gt; 更改为abstract val table: FooTable&lt;M, Any&gt; 就可以了...但是,据我所知,我不能,因为FooTable 的定义很严格第二个参数实现IDto

我该如何解决这个问题?

【问题讨论】:

  • 为什么使用ArrayList作为声明类型?我认为如果您使用 List 这会起作用,因为它是只读的并且可以投影。
  • 我改成了fun getTableData(models: List&lt;M&gt;): List&lt;D&gt;,但现在page.table.getTableData(listOf(m1, m2)).first()这行给了我Type Mismatch: Required List&lt;Nothing&gt; found List&lt;IModel&gt;的错误
  • 如果你准备一个MCVE,你会得到更好的帮助,甚至可以自己解决。
  • 感谢马尔科的建议。我用 MCVE 编辑了我的答案
  • 我看不到任何 MCVE...

标签: kotlin


【解决方案1】:

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

fun testTable(masterModel: IModel, masterTable: FooTable&lt;in IModel, out IDto&gt;)

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

这在here 中得到了解释(尽管您需要花点时间了解一下)。我认为您现有的代码(具有outIModel 泛型类型限制)声明masterTable 参数产生IModels,但没有关于它所接受的规则。因此错误(至少在IntelliJ) 是:

类型不匹配。必需List&lt;Nothing&gt;。找到List&lt;IModel&gt;

因为编译器不知道masterTable 可以接收什么,它不能确定它是否可以接收您试图传递给getTableData 方法的IModel

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-29
    • 2022-12-19
    • 1970-01-01
    • 1970-01-01
    • 2015-02-09
    • 2011-12-04
    • 1970-01-01
    相关资源
    最近更新 更多