In my setup, I'm trying to have an interface Table that inherits from Map (because it will mostly be used as a wrapper around the map). Two classes inherit from Table - local and global. The global one will have a mutable map, and the local one will have a map of only local entries.
// 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)
}
I get the following error:
Type parameter V of 'Map' has inconsistent values: Entry, EntryVar
Why is that? Doesn't Map<String, EntryLocal> inherit from Map<String, Entry>?
You're right the value type of Map is covariant and so a Map<String, EntryLocal> is a Map<String, Entry>.
However, that's not your problem here. The problem is that LocalTable inherits from both Map<String, EntryLocal> (directly) and Map<String, Entry> (via Table) so it's not clear what the value type should be in LocalTable.
In other words, what's the return type of LocalTable.get? Is it Entry or EntryLocal?
Here's the problem in a nutshell:
interface M<T> {}
interface A : M<String> {}
interface B : M<Object> {}
class C : A, B {}
You'll get the same error saying that parameter T of M has inconsistent values. Even though String is an Object, Kotlin won't assume that the type parameter T of the base class M should therefore be String (or Object).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With