How should I go about mapping a string to a class in Haxe, and then instantiating it?
class Foo{}
class Bar extends Foo{}
class Buzz extends Foo{}
// (...)
var classMap:Map<String, Class<Foo>> = [
"abc" => Bar,
"def" => Buzz
];
var myClass:Class<Foo> = classMap["abc"];
var myObj:Foo = new myClass(/* params */);
I thought this would work, but it throws unexpected (
after myClass
. What's wrong?
Instead of storing Class<T>
in the map and resorting to reflection for instantiation, it's a much nicer pattern to store references to the constructors (using their function type) as detailed in this haxe.org blog post.
class Foo {}
class Bar extends Foo {
public function new() {}
}
class Buzz extends Foo {
public function new() {}
}
var constructors:Map<String, Void->Foo> = [
"abc" => Bar.new,
"def" => Buzz.new
];
var construct:Void->Foo = constructors["abc"];
var myObj:Foo = construct();
https://try.haxe.org/#49E93
Unlike the Type.createInstance()
approach, this doesn't allow you to pass arbitrary arguments to the constructors they might not even accept, so it's much more type-safe. It also automatically works with dead code elimination because Haxe sees that the constructors are referenced.
You should use Type.createInstance
to create an instance of that class. new
will only work if you want to directly call the constructor on the Class name itself new Foo()
I suggest you do it this way:
var myClass:Class<Foo> = classMap["abc"];
var myObj:Foo = Type.createInstance(myClass, [/* params */]);
Try it online here: https://try.haxe.org/#3134A
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