【问题标题】:Apply a function on array of values inside Haxe macro对 Haxe 宏中的值数组应用函数
【发布时间】:2017-07-18 15:56:50
【问题描述】:

我在 Haxe 宏中生成了一个 Int 数组,并希望在其上应用一个函数,如下所示:

typedef ComponentIdArray = Array<Int>;

class MyMacros {
    // Each descendant of 'Component' has static member 'id_'
    // Convert array of classes to corresponding indices
    public static macro function classesToIndices(indexClasses:Array<ExprOf<Class<Component>>>) {
        var ixs = [for (indexClass in indexClasses) {macro $indexClass.id_ ;}];
        return macro $a{ixs};
    }

    public static macro function allOf(indexClasses:Array<ExprOf<Class<Component>>>) {
        var indices = macro Matcher.classesToIndices($a{indexClasses});
        // FIXME
        // FIXME 'distinct' is a function from thx.core -- DOES NOT WORK
        //var indices2 = macro ($a{indices}.distinct());
        return macro MyMacros.allOfIndices($indices);
    }


    public static function allOfIndices(indices:ComponentIdArray) {
        trace(indices);
        //... normal function
        // currently I call indices.distinct() here
        return indices.distinct();
    }
}

用法:

class C1 extends Component {} // C1.id_ will be set to 1
class C2 extends Component {} // C2.id_ will be set to 2
var r = MyMacros.allOf(C1, C2, C1); // should return [1,2]

由于一切都是已知的编译时,我想在宏中执行此操作。

【问题讨论】:

  • 你想在宏上下文还是运行时上下文中应用函数?
  • “宏上下文”是否意味着编译时间?好的!基本上,我想在宏中执行此操作的原因是以上所有内容都是已知的comile-time。
  • 虽然答案可能已经解决了,这篇文章也可能对code.haxe.org/category/macros/build-arrays.html有所帮助
  • 马克,谢谢你的贡献!实际上,我已经以那篇文章为起点来生成我的值数组。继续努力!

标签: macros haxe


【解决方案1】:

KevinResoL 的回答基本上是正确的,只是您似乎希望在编译时执行 distinct()(正如您在 try.haxe 的输出选项卡中看到的那样,生成的 JS 代码包含 thx.Arrays.distinct() 调用)。

最简单的解决方案可能是立即在allOf() 中致电distinct()

using haxe.macro.ExprTools;

public static macro function allOf(indexClasses:Array<ExprOf<Class<Component>>>) {
    indexClasses = indexClasses.distinct(function(e1, e2) {
        return e1.toString() == e2.toString();
    });
    var indices = macro Matcher.classesToIndices($a{indexClasses});
    return macro MyMacros.allOfIndices($indices);
}

如您所见,您还需要为distinct() 定义一个自定义predicate,因为您正在比较表达式 - 默认情况下它使用简单的相等检查 (==),这还不够好.

生成的代码如下所示(如果id_ 变量声明为inline):

var r = MyMacros.allOfIndices([1, 2]);

【讨论】:

    【解决方案2】:

    .distinct() 仅在调用函数的模块中有using thx.Arrays 时可用。 当您使用宏生成表达式时,您不能保证调用站点有 using。所以你应该改用静态调用:

    这应该适用于您的代码:

    public static macro function allOf(indexClasses:Array<ExprOf<Class<Component>>>) {
        var indices = macro Matcher.classesToIndices($a{indexClasses});
        var e = macro $a{indices}; // putting $a{} directly in function call will be reified as argument list, so we store the expression first
        return macro thx.Arrays.distinct($e);
    }
    

    另请参阅有关尝试 haxe 的工作示例:http://try-haxe.mrcdk.com/#9B5d6

    【讨论】:

      猜你喜欢
      • 2020-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多