generics - 字段的 setter 被类型投影删除

标签 generics kotlin erasure

我有以下 SSCCE:

class Foo(val bars: Map<Int, Bar<*>>) {

    fun <Baz> qux(baz: Baz) {
        val bar2 = bars[2]!!
        bar2.bazes += baz
    }

    interface Bar<Baz> {
        var bazes: MutableList<Baz>
    }
}

这对我来说似乎很好,但编译器提示:

Error:(5, 9) Kotlin: Setter for 'bazes' is removed by type projection

我不知道这意味着什么,更不用说如何纠正它了。这是怎么回事?我该如何解决?

最佳答案

有几个小问题。暂时使用bars[2]!! as Bar<Baz> ,

w: (4, 20): Unchecked cast: Foo.Bar<Any?> to Foo.Bar<Baz>
e: (5, 20): Assignment operators ambiguity: 
public operator fun <T> Collection<Baz>.plus(element: Baz): List<Baz> defined in kotlin.collections
@InlineOnly public operator inline fun <T> MutableCollection<in Baz>.plusAssign(element: Baz): Unit defined in kotlin.collections

Kotlin 不知道是否将其处理为 bar2.bazes = bar2.bazes.plus(baz)bar2.bazes.plusAssign(baz) 。如果将其更改为 var2.bazes.add(baz)val bazes歧义消失了。

修复该问题并删除不安全的强制转换

e: (5, 20): Out-projected type 'MutableList<out Any?>' prohibits the use of 'public abstract fun add(element: E): Boolean defined in kotlin.collections.MutableList'

关于类型投影可以安全地做什么的问题。它被视为 out Any? ,因此您可以从列表中读取,但是 in Nothing ,这意味着您无法向列表添加任何内容。

从这个示例中不清楚您为什么使用 * 。如果它不会导致任何其他问题,也许您可​​以取出 <Baz>参数,例如

class Foo<Baz>(val bars: Map<Int, Bar<Baz>>)

关于generics - 字段的 setter 被类型投影删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45789446/

相关文章:

java - 如何使 JAXB 实例化通用父类(super class)的子类列表元素

java - 尝试打印 StringBuilder 类型 : "com.jeanlucthumm.poem.Word@7852e922" 时出现奇怪的输出

java - 区别只是 List 和 List<Object> 和 List<?>

gradle - 未找到 Kotlin Gradle 脚本中导入外部类

android - Kotlinx 无法解析符号 "synthetic"

java - 由于相同的删除而导致名称冲突

c# - 使两个并行继承结构跨层交互的方法

c# - 为什么反序列化不起作用?

java - 拆箱时如何检查泛型方法的返回类型以防止 NPE

annotations - 从属性中注释 getter