提供代码
class Test {
static function main() {
var i = 1;
trace(m('some before $i some after')); // some before 1 some after
}
static macro function m(e: haxe.macro.Expr)
{
trace(e); // { expr => EConst(CString(some before $i some after)), pos => #pos(Test.hx:4: characters 12-39) }
// trace the name of referenced var
/*
trace();
*/
return macro $e;
}
}
如果没有手动解析字符串常量,我应该在注释掉的代码中放置trace()
内插String
表达式中使用的变量的名称?
答案 0 :(得分:4)
你想要的是formatString
:
class Test {
#if !macro
static function main() {
var i = 1;
trace(m('some before $i some after')); // some before 1 some after
}
#end
static macro function m(e: haxe.macro.Expr)
{
switch e.expr {
case EConst(CString(s)):
trace(haxe.macro.MacroStringTools.formatString(s, e.pos));
default:
}
return e;
}
}
答案 1 :(得分:2)
输入表达式是一个常量的文字字符串。所以你必须自己解析$i
。以下是使用regular expression的示例,对于奖励积分,请在调用上下文中获取其类型。
http://try-haxe.mrcdk.com/#B0B9E(点击Build+run
,查看输出和编译器输出标签)
import haxe.macro.Expr;
import haxe.macro.Context;
class Test {
static function main() {
var i = 1;
trace(m('some before $i some after')); // some before 1 some after
}
static macro function m(e: Expr)
{
trace(e); // { expr => EConst(CString(some before $i some after)), pos => #pos(Test.hx:4: characters 12-39) }
var interpolated:String = null;
switch e.expr {
case EConst(CString(str)):
trace(str); // 'some before $i some after'
var r = ~/\$\w+/;
if (r.match(str)) { // matched(0) -> $i
interpolated = r.matched(0).substr(1);
trace(interpolated); // 'i'
}
default: throw 'Macro m expects a string literal...';
}
if (interpolated!=null) {
var t = Context.typeof({expr: EConst(CIdent(interpolated)), pos:Context.currentPos()});
trace('Got interpolated var $interpolated of type $t'); // Got interpolated var i of type TAbstract(Int,[])
}
return macro $e;
}
}