如何检查该对象是 Haxe 中的泛型实例
How to check that object is instance of generic in Haxe
我正在寻找一种安全的方法来根据对象类型分叉逻辑。我还没有找到如何检查对象是否属于特定泛型类型的方法。
class Test {
static function main() {
var aa = new AA<Int>();
//ERROR: Cast type parameters must be Dynamic
//var a:A<Int> = cast(aa, A<Int>);
//ERROR: Unexpected )
//var a:A<Int> = Std.instance(aa, A<Int>);
//OK, but throw run-time exception with flash target.
var a:A<Int> = cast aa;
a.printName();
//Run-time exception
a = cast "String is obviously wrong type";
}
}
class A<T> {
public function new () { }
public function printName() {
trace("Generic name: A");
}
}
class AA<T> extends A<T> {
public function new () { super(); }
override public function printName() {
trace("Generic name AA");
}
}
是否有合法的方法来检查对象是否属于泛型?
通常没有很好的方法可以做到这一点,因为信息在运行时不再可用。您可以使用与 often suggested for Java 相同的解决方法,它将通用类型存储在 class:
中
class Main {
static function main() {
var a = new A<Int>(Int);
trace(a.typeParamIs(Int)); // true
trace(a.typeParamIs(Bool)); // false
}
}
class A<T> {
var type:Any;
public function new (type:Any) {
this.type = type;
}
public function typeParamIs(type:Any):Bool {
return this.type == type;
}
}
或者,如果 A
的字段类型为 T
:
,您可以像这样使用 Type.typeOf()
class Main {
static function main() {
checkType(new A<Int>(5)); // Int
checkType(new A<Bool>(true)); // Bool
checkType(new A<B>(new B())); // B
checkType(new A<B>(null)); // unhandled type TNull
}
static function checkType<T>(a:A<T>) {
trace(switch (Type.typeof(a.value)) {
case TInt: "Int";
case TBool: "Bool";
case TClass(cls) if (cls == B): "B";
case other: throw "unhandled type " + other;
});
}
}
class A<T> {
public var value:T;
public function new (value:T) {
this.value = value;
}
}
class B {
public function new() {}
}
如您所见,虽然这通常有效,但在某些情况下可能会导致意外行为 - 例如当 value
为 null
时。还要记住 Type.typeOf()
:
的文档
May vary per platform. Assumptions regarding this should be minimized to avoid surprises.
进一步阅读:mailing list thread 前段时间讨论过这个问题。那里提到了一个宏解决方案,以防你不需要在运行时知道类型。
我正在寻找一种安全的方法来根据对象类型分叉逻辑。我还没有找到如何检查对象是否属于特定泛型类型的方法。
class Test {
static function main() {
var aa = new AA<Int>();
//ERROR: Cast type parameters must be Dynamic
//var a:A<Int> = cast(aa, A<Int>);
//ERROR: Unexpected )
//var a:A<Int> = Std.instance(aa, A<Int>);
//OK, but throw run-time exception with flash target.
var a:A<Int> = cast aa;
a.printName();
//Run-time exception
a = cast "String is obviously wrong type";
}
}
class A<T> {
public function new () { }
public function printName() {
trace("Generic name: A");
}
}
class AA<T> extends A<T> {
public function new () { super(); }
override public function printName() {
trace("Generic name AA");
}
}
是否有合法的方法来检查对象是否属于泛型?
通常没有很好的方法可以做到这一点,因为信息在运行时不再可用。您可以使用与 often suggested for Java 相同的解决方法,它将通用类型存储在 class:
中class Main {
static function main() {
var a = new A<Int>(Int);
trace(a.typeParamIs(Int)); // true
trace(a.typeParamIs(Bool)); // false
}
}
class A<T> {
var type:Any;
public function new (type:Any) {
this.type = type;
}
public function typeParamIs(type:Any):Bool {
return this.type == type;
}
}
或者,如果 A
的字段类型为 T
:
Type.typeOf()
class Main {
static function main() {
checkType(new A<Int>(5)); // Int
checkType(new A<Bool>(true)); // Bool
checkType(new A<B>(new B())); // B
checkType(new A<B>(null)); // unhandled type TNull
}
static function checkType<T>(a:A<T>) {
trace(switch (Type.typeof(a.value)) {
case TInt: "Int";
case TBool: "Bool";
case TClass(cls) if (cls == B): "B";
case other: throw "unhandled type " + other;
});
}
}
class A<T> {
public var value:T;
public function new (value:T) {
this.value = value;
}
}
class B {
public function new() {}
}
如您所见,虽然这通常有效,但在某些情况下可能会导致意外行为 - 例如当 value
为 null
时。还要记住 Type.typeOf()
:
May vary per platform. Assumptions regarding this should be minimized to avoid surprises.
进一步阅读:mailing list thread 前段时间讨论过这个问题。那里提到了一个宏解决方案,以防你不需要在运行时知道类型。