The code:
abstract class DataContainer(public val path: String)
val preloaded: MutableMap<Class<out DataContainer>, HashSet<out DataContainer>> = hashMapOf()
I would like to know how to make Kotlin realize that the first out DataContainer
is the same type as the second out DataContainer
.
So that code like:
fun <D: DataContainer> get(clazz: Class<D>): HashSet<D> = preloaded[clazz] as HashSet<D>
Doesn't require as HashSet<D>
(and isn't prone to casting errors).
I am new to Kotlin, so do link documentation if I've missed something.
Also, this code would be inside an object
if it matters.
I don't think that what you want is feasible at a language level.
A cast in the get
method isn't that bad as long as you can do it safely. The only way I can see to do that safely is to control the put
method as well.
If you enforce that each key of type D : DataContainer
will be paired with a key of type Set<D>
, you can safely cast when getting. For instance you could something like this:
object DataContainerRegistry {
private val preloaded: MutableMap<Class<out DataContainer>, HashSet<DataContainer>> = hashMapOf()
fun put(dataContainer: DataContainer) {
val set = preloaded.getOrDefault(dataContainer::class.java, HashSet())
set.add(dataContainer)
preloaded[dataContainer::class.java] = set
}
fun <D : DataContainer> get(clazz: Class<D>) = preloaded.getOrDefault(clazz, HashSet()) as Set<D>
}
The limitations of this method are:
DataContainerRegistry
singleton in my example) will have direct access to the preloaded
map get
method will return only Set
, not the mutable interface. This way you know that nobody will mess up preloaded
and each Set
contained in it, and you can then cast light-heartedly.
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