Search code examples
classdictionarytypeshaxe

Haxe - mapping a string to a class


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?


Solution

  • 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.