- Haxe宏方法是一种特殊方法,它的生命周期处于且仅处于编译期。
- 包含宏的代码编译分三个阶段,首先根据有效代码生成Abstract Syntax Tree,然后找到宏方法并执行(会执行上下文中相关的代码,所以需要将宏方法隔离),最后宏方法变成haxe代码。
- 在宏方法中,所有对象都是Expr,加macro关键字可以使得表达式不立即执行,而是作为结果代码置入目标位置,该表达式不能直接与任何外部变量交互,类似lisp的’,传入的变量必须以Context.makeExpr(x, Context.currentPos())转为Expr才能用于返回表达式。
例如:
//类1 import haxe.macro.Context; import haxe.macro.Expr; class TypeBuildingMacro { macro static public function build(fieldName:String):Array<Field> { var fields = Context.getBuildFields(); var newField = { name: fieldName, doc: null, meta: [], access: [AStatic, APublic], kind: FVar(macro : String, macro "my default"), pos: Context.currentPos() }; fields.push(newField); return fields; } } //类2 @:build(TypeBuildingMacro.build("myFunc"))//@:build代表在该类编译时调用其后代码块 class Main { static public function main() { trace(Main.myFunc); // my default } }
// TimesLoop.hx import haxe.macro.Expr; import haxe.macro.Context; class TimesLoop { @:macro public static function times( n : Int, e:Expr ) : Expr { var n_expr = Context.makeExpr(n, Context.currentPos()); return macro for (i in 0...$n_expr) { $e; }; } } // HelloWorld.hx import TimesLoop; using TimesLoop; class HelloWorld { public static function main() { 5.times( trace("HelloWorld") ); var x = 0; 5.times( trace(x++)); } }