zsperske
08/04/2021, 8:02 PMinterface SchemaFactory<in E: Event, out S: Schema> {
fun create(event: E) : S
}
class TestEventFactory : SchemaFactory<TestEvent, TestEventSchema>
private val factories: Map<Class<out Event>, SchemaFactory<Event, Schema>> = mapOf(TestEvent::class.java to TestEventFactory())
However I get the following error message on `factories`:
Type mismatch.
Required:
Map<Class<out Event>, SchemaFactory<Event, Schema>>
Found:
Map<Class<out Event>, TestEventFactory>
Ruckus
08/04/2021, 8:08 PMTestEventFactory
is not a SchemaFactory<Event, Schema>
(due to the in
variance)TestEventFactory
cannot take in any event, only `TestEvent`s.zsperske
08/04/2021, 8:15 PMRuckus
08/04/2021, 8:18 PMclass AllFactories {
private val factories: Map<Class<out Event>, SchemaFactory<*, *>> =
mapOf(TestEvent::class.java to TestEventFactory())
operator fun <E : Event> get(type: Class<out E>): SchemaFactory<E, Schema> {
@Suppress("UNCHECKED_CAST")
return factories[type] as SchemaFactory<E, Schema>
}
}
zsperske
08/04/2021, 8:19 PMRuckus
08/04/2021, 8:20 PMzsperske
08/04/2021, 8:21 PMRuckus
08/04/2021, 8:28 PMMap
interface does not enforce any sort of relation between the type of the keys and values, so there's no way to say "a key of Class<T> will always point to a value of T". You can make your own type to do that (which is essentially what AllFactories
is, it just happens to use a Map
for an easy implementation). In the end, there will likely have to be an "unsafe" cast somewhere.
"Unsafe" doesn't mean it isn't safe per say, just that the compiler cannot guarantee it's safe, so it's on you to do so. ArrayList
has to do this, for example, as under the covers it's using Array<Any>
(I guess Object[]
on the JVM since it's a Java class), so the get(Int)
calls basically do elements[index] as T
, which is also an "unsafe" cast.zsperske
08/04/2021, 8:31 PMRuckus
08/04/2021, 8:37 PMMap<Class<T>, T>
and Map<Class<T>, Item<T>>
(that is, a map from classes to values of the class type vs from classes to some other type that happens to share a generic type with the class), so there isn't really a one size fits all solution.zsperske
08/04/2021, 8:48 PMephemient
08/04/2021, 10:07 PMMap