我想将模型的实例存储在一个公共(public)提供者中,使用它们的类或接口(interface)作为键,然后通过类引用弹出它们。我写了一些代码:
class Provider {
public function new() { }
public function set<T:Any>(instance:T, ?type:Class<T>) {
if (type == null)
type = Type.getClass(instance);
if (type != null && instance != null)
map.set(type, instance);
}
public function get<T:Any>(type:Class<T>):Null<T> {
return cast map.get(type);
}
var map = new Map<Class<Any>, Any>();
}
...唉,它甚至不能编译。 可能我必须使用合格的类名作为键而不是类/接口(interface)引用?但我想保持整洁的 get 函数设计,该函数将类型作为参数并返回所采用类型的对象,而无需额外的类型转换。
是否有可能或者我应该改变我解决这个问题的方法?
最佳答案
使用问题 Class<T>
作为Map
key 经常出现,here是一个相关的讨论。 Map<Class<T>, T>
的天真方法无法用这样的东西编译:
Abstract haxe.ds.Map has no @:to function that accepts haxe.IMap<Class<Main.T>, Main.T>`
有几种不同的方法可以解决这个问题:
可以使用
Type
反射以获取类实例的完全限定名称,然后将其用作Map<String, T>
中的键:var map = new Map<String, Any>(); var name = Type.getClassName(Main); map[name] = value;
为方便起见,您可能希望有一个包装器来为您完成此操作,例如 this
ClassMap
implementation .
一个更简单的解决方案是通过使用空结构类型 (
{}
) 作为键类型来“欺骗”Haxe 编译它。这导致ObjectMap
被选为底层 map 实现。var map = new Map<{}, Any>(); map[Main] = value;
但是,这允许您将事物用作非
Class<T>
类型的键。 ,例如:map[{foo: "bar"}] = value;
可以使用 this
ClassKey
abstract 解决之前方法的类型安全问题。 :@:coreType abstract ClassKey from Class<Dynamic> to {} {}
这还是用
ObjectMap
由于to {}
,作为基础 map 实现implicit cast .但是,现在使用结构作为键在编译时会失败:var map = new Map<ClassKey, Any>(); map[{foo: "bar"}] = value; // No @:arrayAccess function accepts arguments [...]
关于inversion-of-control - 在 Haxe 中使用 Class<T> 作为 Map 键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54600290/