Ellen Spertus
11/01/2022, 8:46 PMMob
(abstract), Zombie
, and Spider
. I would like to create a class Spawner<T: Mob>
to create, for example, Spider Spawners (blocks that periodically construct and place new instances of Spider
). I'm trying to figure out the best way to instantiate a new instance of T
from within Spawner<T>
. I tried the following, but it doesn't work because of type erasure:
class Spawner<T: Mob> {
fun spawn() {
val constructor = T::class.constructors.find { it.parameters.isEmpty() } // error: Cannot use 'T' as reified type parameter
val newMob = constructor?.call()
}
}
I'd rather not require the students to create factory classes. (This is an introductory programming class.) Instead I was thinking of faking a factory with a copy()
method:
class Spawner<T: Mob>(val mob: T) {
fun spawn() {
val newMob = mob.copy()
// Place newMob on game board.
}
}
abstract class Mob {
abstract fun copy(): Mob
}
class Pigman: Mob() {
override fun copy() = Pigman()
}
fun main() {
val pigmanSpawner = Spawner<Pigman>(Pigman())
pigmanSpawner.spawn()
}
Something I don't like about this is the type parameter isn't used and could be removed (if I changed the type of the mob
property from T
to Mob
).ephemient
11/01/2022, 8:52 PMclass Spawner<out T: Mob>(val newMob: () -> T) {
fun spawn() {
val newMob = newMob()
val pigmanSpawner = Spaner(::Pigman)
with some better naming but that should be the ideaEllen Spertus
11/01/2022, 10:14 PMfilterIsInstance<T>
Matteo Mirk
11/03/2022, 11:09 AMinline fun <reified T : Mob> spawn() : T {
val constructor = T::class.constructors.first { it.parameters.isEmpty() }
return constructor.call()
}
fun main() {
val z = spawn<Zombie>()
}
I replaced ‘find’ with ‘first’ that produces a non-nullable type or throws if the element is not found.ephemient
11/04/2022, 12:59 AMT::class.createInstance()
ephemient
11/04/2022, 1:00 AMMatteo Mirk
11/04/2022, 1:17 PMEllen Spertus
11/06/2022, 9:50 PMSpawner<T>
and tested it out with Spawner<Zombie>
, I realized I could create Spawner<Spawner<Zombie>>
and did so. 🧟