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

Luk*_*dič 3 generics covariance kotlin

在我的设置中,我试图有一个Table继承自的接口Map(因为它主要用作地图的包装器)。两个类继承自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)

}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

Type parameter V of 'Map' has inconsistent values: Entry, EntryVar
Run Code Online (Sandbox Code Playgroud)

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

Wil*_*urn 5

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

然而,这不是你的问题。问题是,LocalTable从两个继承Map<String, EntryLocal>(直接)和Map<String, Entry>(通过Table),因此目前还不清楚值类型应该是什么LocalTable

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

简而言之,问题如下:

interface M<T> {}
interface A : M<String> {}
interface B : M<Object> {}
class C : A, B {}
Run Code Online (Sandbox Code Playgroud)

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