【问题标题】:Haxe - mapping a string to a classHaxe - 将字符串映射到类
【发布时间】:2019-08-27 05:06:49
【问题描述】:

我应该如何将一个字符串映射到 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 (。怎么了?

【问题讨论】:

    标签: class dictionary types haxe


    【解决方案1】:

    与其将Class&lt;T&gt; 存储在映射中并借助反射进行实例化,不如存储对构造函数的引用(使用它们的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() 方法不同,这不允许您将任意参数传递给它们甚至可能不接受的构造函数,因此它的类型安全性更高。它还自动与 dead code elimination 一起使用,因为 Haxe 看到构造函数被引用。

    【讨论】:

    • 如果构造函数期望不同类型的参数怎么办?
    • 我的意思是,那么Map 方法就失去了意义。即使使用Type.createInstance(),您也必须检查 String 键来决定要传递哪些参数。
    【解决方案2】:

    您应该使用Type.createInstance 创建该类的实例。 new 仅在您想直接调用类名本身的构造函数时才有效new Foo()

    我建议你这样做:

    var myClass:Class<Foo> = classMap["abc"];
    var myObj:Foo = Type.createInstance(myClass, [/* params */]);
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-23
      • 2012-08-21
      • 1970-01-01
      • 1970-01-01
      • 2011-02-10
      • 2020-09-04
      • 1970-01-01
      相关资源
      最近更新 更多