【问题标题】:How to get the parameter type of the class method with macro?如何用宏获取类方法的参数类型?
【发布时间】:2019-05-02 15:38:18
【问题描述】:

如何用宏获取类方法的参数类型?

class A{
 public function new(){
  //this how get method out arg[0] Type with macro?
  var arg0IsInt:Bool=arg0IsInt(out);
 }
 public function out(a:Int){ return true; }

 macro public function arg0IsInt(e:Expr):Bool{
 } 

}

当我构造一个字母时,我将调用一个具有类型参数的方法。

【问题讨论】:

    标签: macros haxe


    【解决方案1】:

    您可以将out 传递给表达式宏,然后在其上使用Context.typeof()。结果将是 function type (TFun),您可以使用 pattern matching 检查其第一个参数。

    这是一个工作示例:

    import haxe.macro.Context;
    import haxe.macro.Expr;
    
    class Main {
        static function main() {
            new Main();
        }
    
        public function new() {
            trace(arg0IsInt(out)); // true
            trace(arg0IsInt(out2)); // false
        }
    
        public function out(a:Int) {}
    
        public function out2(a:Float) {}
    
        macro static function arg0IsInt(func:Expr):Expr {
            return switch Context.typeof(func) {
                case TFun(args, _):
                    switch args[0].t {
                        case TAbstract(_.get() => t, _) if (t.name == "Int" && t.pack.length == 0):
                            macro true;
                        case _:
                            macro false;
                    }
                case _:
                    throw 'argument should be a function';
            }
        }
    }
    

    Int 是一个abstract,为了确保它不只是一些在其他包中恰好被命名为Int 的随机抽象,我们检查它是否在顶级包(pack.length == 0)中。

    【讨论】:

      【解决方案2】:

      事实上,你可以在模式匹配方面走得更远:

      import haxe.macro.Context;
      import haxe.macro.Expr;
      
      class Test {
          static function main() {
              new Test();
          }
      
          public function new() {
              trace(arg0IsInt(out)); // true
              trace(arg0IsInt(out2)); // false
          }
      
          public function out(a:Int) {}
      
          public function out2(a:Float) {}
      
          macro static function arg0IsInt(func:Expr):Expr {
              return switch Context.typeof(func) {
                  case TFun(_[0] => {t: TAbstract(_.get() => {name: 'Int', pack: []}, _)}, _): macro true;
                  case TFun(_): macro false;
                  case _: throw 'argument should be a function';
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2013-02-03
        • 2013-06-14
        • 1970-01-01
        • 2022-01-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多