Kotlin class 层次结构和(协)方差

Kotlin class hierarchy and (co)variance

在我的设置中,我尝试使用一个继承自 Map 的接口 Table(因为它主要用作地图的包装器)。两个 类 继承自 Table - 局部和全局。全局的将有一个可变的映射,而本地的将有一个只有本地条目的映射。

// entries
sealed class Entry {
    class EntryLocal : Entry
    class EntryGlobal : Entry
}

interface Table : Map<String, Entry> {
    fun getRecursive(key: String): Entry?   
}

class GlobalTable(val map:MutableMap<String, Entry>) : Table, Map<String, Entry> by map {
    override fun getRecursive(key: String) = this[key]

    ...
}

class LocalTable(
    private val parent: Table,
    val map: Map<String, EntryLocal>
) : Table, Map<String, EntryLocal> { // gives error
    override fun getRecursive(key: String): Entry? = map[key] ?: parent.getRecursive(key)

}

我收到以下错误:

Type parameter V of 'Map' has inconsistent values: Entry, EntryVar

这是为什么? Map<String, EntryLocal> 不是继承自 Map<String, Entry> 吗?

你是对的 Map 的值类型是协变的,所以 Map<String, EntryLocal>Map<String, Entry>.

但是,这不是您的问题。问题是 LocalTable 继承自 Map<String, EntryLocal>(直接)和 Map<String, Entry>(通过 Table),因此不清楚 LocalTable 中的值类型应该是什么.

换句话说,LocalTable.get的return类型是什么?是 Entry 还是 EntryLocal

问题简述如下:

interface M<T> {}
interface A : M<String> {}
interface B : M<Object> {}
class C : A, B {}

你会得到同样的错误,指出 M 的参数 T 的值不一致。即使 String 是一个 Object,Kotlin 也不会假设基础 class M 的类型参数 T 因此应该是 String (或 Object)。