当前位置: 首页 > 知识库问答 >
问题:

kotlin泛型:无法推断类型参数

夹谷山
2023-03-14

我需要 Kotlin 中的一个集合来仅包含实现给定接口的元素。

例如:包含动物集合的地图:

interface Animal { val name: String }
data class Monkey(override val name: String): Animal
data class Snake(override val name: String): Animal

通过阅读文档、博客和SO问题,我编写了使用Generics in关键字的代码:

class Test {
    private val data = HashMap<String, ArrayList<in Animal>>()        
    init {
        data.put("Monkeys", arrayListOf(Monkey("Kong"), Monkey("Cheetah")))
        data.put("Snakes", arrayListOf(Snake("Monthy"), Snake("Kaa")))
    }        
}

现在我想在Test类中添加一个读取“data”内容的方法,例如将其打印到控制台:

fun printAll() {
   data.forEach { collectionName: String, animals: ArrayList<in Animal> -> 
       println(collectionName)
       animals.forEach { animal: Animal ->
           println("\t$animal")
       }
    }
}

如果我这样做,我会遇到编译错误:

Error:(27, 21) Kotlin: Type inference failed: Cannot infer type parameter T in inline fun <T> Iterable<T>.forEach(action: (T) -> Unit): Unit
None of the following substitutions
receiver: Iterable<Any?>  arguments: ((Any?) -> Unit)
receiver: Iterable<Animal>  arguments: ((Animal) -> Unit)
can be applied to
receiver: kotlin.collections.ArrayList<in Animal> /* = java.util.ArrayList<in Animal> */  arguments: ((Animal) -> Unit)

我的解决方案是强制我的动物进入一个ArrayList

...
(animals as ArrayList<out Animal>).forEach { animal: Animal ->
    println("\t$animal")
}
...

但是我不确定这是编写这种代码的最好方式。有没有更好的方式告诉Kotlin我想在泛型中为生产者和消费者使用子类型?

共有1个答案

颛孙麻雀
2023-03-14

我想在< code>data类型中不需要< code>in关键字。

在中使用意味着您希望那些ArrayLists的类型参数至少与 一样通用,这意味着<code>ArrayList

考虑删除关键字中的,只保留ArrayList

private val data = HashMap<String, List<Animal>>()

init {
    data.put("Monkeys", listOf(Monkey("Kong"), Monkey("Cheetah")))
    data.put("Snakes", listOf(Snake("Monthy"), Snake("Kaa")))
}

fun printAll() {
    data.forEach { collectionName: String, animals: List<Animal> ->
        println(collectionName)
        animals.forEach { animal: Animal ->
            println("\t$animal")
        }
    }
}

 类似资料:
  • 问题内容: 我正在为核心数据编写通用包装类。 这是我的一些基本类型。没什么特别的。 我已经将我的coredata写在协议中抽象化了。如果您让我知道您对我要提出的抽象的意见,我将不胜感激。但是在扩展中,我遇到了以下错误: 无法将类型“ NSFetchRequest”的值转换为预期的参数类型“ NSFetchRequest <_>” 不确定我该如何解决。我尝试了各种更改代码的尝试,但未成功…… 另外,

  • 我的分类测试应用程序有一个问题,我使用了一个比较器。我收到一条信息: 线程“主”java.lang 中的异常:未解决的编译问题:无法推断排序器的类型参数 对于该代码: 分拣机类: 可比接口: id比较器类: 比较器接口: 这样用有什么错?我怎样才能做得更好?

  • 我使用一个密封类从网络返回数据。但是当我在构建这个项目时,我得到了以下错误 类型推断失败:没有足够的信息来推断参数T in fun error(错误消息:String,错误:Throwable):状态请明确指定它。 我错过了什么? 这是代码

  • 我仍然在玩我的日历,我已经设法将 https://github.com/SundeepK/CompactCalendarView 整合到我的一个片段中。只剩下一个错误,我做了一些研究,其他人也遇到了问题,例如使用ArrayList 示例代码: IDE说: 注:C:...\Uebersicht.java使用或覆盖不推荐使用的API。注意:用-Xlint:deprecation重新编译以获得详细信息。

  • 我试着做一个ArrayList,包含另一个类的对象,一个名字,还有turn。类似于python字典的东西。 所以我做了一个有三个值的类。 我试图在主类的构造函数中调用它,如下所示: 但它引发了一个错误:无法推断ArrayList的类型参数

  • 我想实现Spring endpoint,在其中我可以返回XML对象< code > notification echo response 和http状态代码。我试过这个: 但是我收到错误: