完成@:op(a.b)

时间:2017-02-17 11:50:39

标签: haxe

此处描述@:op(a.b)功能:https://haxe.io/releases/3.3.0/ 我有May<T>摘要用于空安全。以下是它的简化版本:

package;
import haxe.macro.Expr;

abstract May<T>(Null<T>) from(Null<T>){

    // convert T, Null<T> or May<T> to May<T>
    // accepts Null<T because of 'from(Null<T>)' 
    // accepts T because Null<T> has 'from(T)'
    // we need to accept May<T> to avoid returning May<May<T>> from resolve() if field is already a May
    public static inline function from<T>(t:May<T>):May<T> return t; 

    public inline function exist():Bool return this != null;

    public inline function unwrap():T return exist() ? unsafeUnwrap() : throw 'unwrap null';

    public inline function unwrapOr(defaultValue:T):T return exist() ? unsafeUnwrap() : defaultValue;

    public inline function unsafeUnwrap():T return this;

    // return same field from underlying type but as May<FieldType>
    @:op(a.b) static macro function resolve<T>(ethis:ExprOf<May<T>>, name:String):Expr {
        return macro {
            var me = $ethis;
            var result = May.from(me.exist() ? me.unsafeUnwrap().$name : null);
            result;
        }
    }
}

请注意resolve()功能。这是我要添加到实际May摘要中的新功能。它允许安全地从May获取字段并仅调用unwrap()一次。例如:

may.exist() ? may.unwrap().someField : defaultValue

变为

may.someField.unwrapOr(defaultValue)

这非常方便,效果很好。但完成不起作用。它仅提供Mayunwrap()exist()等字段,但不包含基础类中的字段。

我决定添加@:forward元数据以便完成:

#if display @:forward #end

这使编译器在完成期间查看所有字段。它总比没有好,但是字段的类型不正确:T而不是May<T>,所以我没有完成May字段。

我理解为什么编译器在使用@:op(a.b)时无法知道所有可能的字段,但也许有一些更聪明的技巧会有所帮助?

0 个答案:

没有答案