Haxe宏函数

  • 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++));
  }
}

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注