检查仅存在于子 class 中的字段的最佳方法?

Best method for checking field present only in child class?

我正在编写一个比较函数,我需要检查 class 特定字段的值,当这些字段存在于两个对象中时。自然地,Haxe 的编译时检查会抛出错误,因为接口不包含该字段。

我已经尝试包装检查字段(Std.is(record, MX)Reflect.hasField(record,'prio'))的代码以及安全转换:

        try {
            cast(record, MX);
            return compareNumber(this.prio, record.prio);
        } catch(error:Dynamic) {
            //do nothing because we figured out type earlier in the code.
        }

编译器似乎没有注意到。我想出的最佳解决方法是将其传递给具有 Dynamic 类型的便捷函数。

将变量分配给其自身类型更严格的版本似乎已解决问题:

public function compare(record:InterfaceName):Int{

    var result = super.compare(record);  //checks of all common fields which also happens to determine type

    if(result == 0){
        try{
            var record:MX = cast(record, MX);
            return compareNumber(this.prio, record.prio);
        } catch(error:Dynamic){
            //do nothing
        }
    }


    return result;
}

但是,safe cast and type check 上的文档不包含此步骤(尽管类型检查条目实际上没有示例),我怀疑有更好的解决方案。

推荐的方法是使用 Std.instance,它调用 Std.iscast:

var result = super.compare(record);
var sub = Std.instance(record, MX);  // returns either record:MX or null
if (result == 0 && sub != null)
    result = compareNumber(this.prio, sub.prio);
return result;

由于 Std.instance 首先检查转换是否可行,因此它可以使用更快的不安全转换。实现很容易遵循:JS, C++.


关于您的问题示例的说明:它不起作用的原因是 cast(record, MX) 本身不会更改该声明后的类型(它们可能会更改 [=16 的推断类型=] 如果它是单形体,但我认为在这种情况下不允许安全转换)。转换是表达式,就像 Haxe 中的其他所有内容一样,为了使它们有用,您需要将它们的结果分配给某个变量(就像您在回答中所做的那样,但显式键入变量是可选的)。