@:op(a.b)这里描述了这个功能:https://haxe.io/releases/3.3.0/
我有May<T>一个用于null安全的摘要.这是它的简化版本:
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
注意这个resolve()功能.这是我想要添加到我的实际May摘要中的新功能.它允许安全地从中获取字段May并unwrap()仅调用一次.例如:
may.exist() ? may.unwrap().someField : defaultValue
Run Code Online (Sandbox Code Playgroud)
变
may.someField.unwrapOr(defaultValue)
Run Code Online (Sandbox Code Playgroud)
这非常方便,效果很好.但完成不起作用.它只是给出了场May:unwrap(),exist()等等,但没有从根本类字段.
我决定添加@:forward元数据以完成:
#if display @:forward #end
Run Code Online (Sandbox Code Playgroud)
这使编译器在完成期间查看所有字段.它总比没有好,但字段的类型不正确:T而不是May<T>,所以我没有完成May字段.
我理解为什么编译器在使用时无法知道所有可能的字段@:op(a.b),但也许有一些更聪明的技巧会有所帮助?