此处描述@: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)
这非常方便,效果很好。但完成不起作用。它仅提供May
:unwrap()
,exist()
等字段,但不包含基础类中的字段。
我决定添加@:forward
元数据以便完成:
#if display @:forward #end
这使编译器在完成期间查看所有字段。它总比没有好,但是字段的类型不正确:T
而不是May<T>
,所以我没有完成May
字段。
我理解为什么编译器在使用@:op(a.b)
时无法知道所有可能的字段,但也许有一些更聪明的技巧会有所帮助?