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
)。
在我的设置中,我尝试使用一个继承自 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
)。