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)

}

我收到以下错误:

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

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

回答

你是对的,值类型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 {}

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


以上是Kotlin类层次结构和(协)方差的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>