我在Haxe 3上有这样的代码:
macro public static function get(key:String)
{
return Context.makeExpr(Context.definedValue(key), Context.currentPos());
}但是,在迁移到Haxe 4之后,这不能进行错误的编译:
未指明的异常宏宏
如何将此函数迁移到Haxe 4?是否有更好的方法访问构建标志以避免此问题?
发布于 2020-08-27 11:46:32
最后,我们删除了整个get方法,转而使用Compiler.getDefine(),这是Haxe 3和4所支持的。
我相信我们所面临的问题与这样一个事实有关:这个静态宏get是从我们的测试运行程序脚本中调用的,所以可能就是一个宏调用另一个宏的地方。尽管如此,我还是试图把杰夫·沃德提出的解决方案摆在适当的位置,但一直得到同样的结果。
发布于 2020-08-11 22:50:54
正如@Gama11 11所暗示的那样,您的宏函数实际上没有问题,您从哪里调用它也有问题。(Haxe 4可能对这些检查更加严格。)
如果你有:
Main.hx
class Main
{
public static function main()
{
// Can call get from here:
var cvar = MacroUtil.get('cvar');
MacroUtil.some_macro_function();
trace('Hello world! cvar=${ cvar }');
}
}MacroUtil.hx
import haxe.macro.Context;
import haxe.macro.Expr;
class MacroUtil
{
macro public static function get(key:String):Expr
{
return Context.makeExpr(Context.definedValue(key), Context.currentPos());
}
macro public static function some_macro_function()
{
// Cannot call get from here:
var cvar:Expr = get('cvar');
trace('will trace at compile time, and cvar is ${ cvar }');
return macro trace('will trace at runtime');
}
}并使用:haxe -x Main -D cvar=abc执行它。
这将产生您正在经历的错误。这是因为在some_macro_function中,您已经处于宏上下文中,因此不能从那里调用宏函数get。
有几种方法可以解决这个问题。
一种方法
您可以使用#if macro / if !macro检测宏上下文并进行相应的调整。因此,尽管这看起来很愚蠢,但它确实解决了您的特定问题:
class MacroUtil
{
#if !macro macro #end public static function get(key:String):Expr
{这个函数签名说,如果我已经在宏上下文中,不要认为这个函数是宏函数。在这一点上,它只是一个静态助手。记住它返回一个Expr,而不是一个字符串,就像它在主上下文中所做的那样。
如果将宏函数和非宏函数混合在一个文件中,您可能还需要使用#if macro来避免这种情况。
另一种方法
您可以将宏函数重构为宏函数和宏助手。它有点冗长,但也许对正在发生的事情更加清楚:
MacroUtil.hx
import haxe.macro.Context;
import haxe.macro.Expr;
class MacroUtil
{
macro public static function get(key:String):Expr
{
return Context.makeExpr(MacroHelpers.get_define(key), Context.currentPos());
}
macro public static function some_macro_function()
{
// Cannot call get from here:
var cvar:String = MacroHelpers.get_define('cvar');
trace('will trace at compile time, and cvar is ${ cvar }');
return macro trace('will trace at runtime');
}
}
class MacroHelpers
{
public static function get_define(key:String):String
{
return Context.definedValue(key);
}
}如果这样做,则宏函数都调用MacroHelpers,而非宏函数调用MacroUtils。注意,助手返回一个字符串,然后由调用站点将其转换为表达式,如果这是他们想要的话。
https://stackoverflow.com/questions/63364360
复制相似问题