繁体   English   中英

在Haxe宏中的值数组上应用函数

[英]Apply a function on array of values inside Haxe macro

我在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]

因为编译时一切都是已知的,所以我想在宏中执行此操作。

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

最简单的解决方案可能就是在allOf()allOf()调用distinct() allOf()

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]);

.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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM