Haxe - 将字符串映射到类

4

我应该如何在Haxe中将一个字符串映射到一个类,并实例化它?

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 */);

我以为这个会起作用,但它拋出了myClass后面的unexpected (。有什么问题吗?
2个回答

7

不要在映射中存储Class<T>并使用反射进行实例化,更好的模式是存储构造函数的引用(使用它们的function type),如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

Type.createInstance() 方法不同,这种方法不允许您传递可能甚至不接受的任意参数给构造函数,因此更加类型安全。它还会自动与 死代码消除 一起使用,因为Haxe会看到构造函数被引用了。

如果构造函数期望不同类型的参数,该怎么办? - Mateusz Sowiński
我的意思是,这样Map的方法就失去了它的意义。即使使用Type.createInstance(),你仍然需要检查字符串键来决定要传递哪些参数。 - Gama11

2
你应该使用 Type.createInstance 来创建该类的实例。如果你想要直接在 Class 名称本身上调用构造函数,则只能使用 new Foo(),而 new 只能工作在这种情况下。
我建议您按照以下方式操作:
var myClass:Class<Foo> = classMap["abc"];
var myObj:Foo = Type.createInstance(myClass, [/* params */]);

在这里在线尝试: https://try.haxe.org/#3134A

最初的回答:


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接