[英]Apply a function on array of values inside Haxe macro
I generate an array of Int
inside Haxe macro and would like to apply a function on it like this: 我在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();
}
}
Usage: 用法:
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]
Since everything is known compile-time I would like to do this in macro. 因为编译时一切都是已知的,所以我想在宏中执行此操作。
KevinResoL's answer is basically correct, except it seems you want distinct()
to be executed at compile-time (as you can see in try.haxe's output tab, the generated JS code contains the thx.Arrays.distinct()
call). KevinResoL的答案基本上是正确的,除了你似乎想要在编译时执行distinct()
(正如你在try.haxe的输出选项卡中看到的那样,生成的JS代码包含thx.Arrays.distinct()
调用)。
The easiest solution is probably to call distinct()
right away in allOf()
: 最简单的解决方案可能就是在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);
}
As you can see, you also need to define a custom predicate
for distinct()
, since you're comparing expressions - by default it uses a simple equality check ( ==
), which isn't good enough. 如您所见,您还需要为distinct()
定义自定义predicate
,因为您正在比较表达式 - 默认情况下它使用简单的相等性检查( ==
),这不够好。
The generated code looks like this (if the id_
variables are declared inline
): 生成的代码如下所示(如果id_
变量是inline
声明的):
var r = MyMacros.allOfIndices([1, 2]);
.distinct()
is only available when you have using thx.Arrays
in the module calling the function. .distinct()
仅在调用函数的模块中using thx.Arrays
时可用。 When you generate the expression with macro, you cannot guarantee the callsite has the using
in place. 使用宏生成表达式时,无法保证调用点具有using
位置。 So you should use the static call instead: 所以你应该使用静态调用:
This should work for your code: 这适用于您的代码:
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);
}
Also see this working example on try haxe: http://try-haxe.mrcdk.com/#9B5d6 另请参阅这个有关haxe的工作示例: http ://try-haxe.mrcdk.com/#9B5d6
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.