注意:我的问题#4417已经关闭,但我不想成为那个为同样的事情打开另一个问题的人。
基于#3132,[ { "a": 1, "b": 2 }, { "a": 2 } ]
除非您专门将其键入Array<Dynamic>
或包含两者的任何类型,否则不会编译。我觉得这很好,但是在下面的构建宏中,我无处可以输入数组,而且我收到错误。
一般情况下,我可以使用untyped
(http://try.haxe.org/#3dBf5)制作地图文字符号,但由于我的类型尚未构建,因此我无法在此处执行此操作。< / p>
macro public static function test():Array<Field> {
var fields = Context.getBuildFields();
// parse the JSON
var o = Context.parseInlineString('{ "arr": [ { "a": 1, "b": 2 }, { "a": 2 } ] }', Context.currentPos());
// ["test" => json] map literal notation
var a = [{ expr : EBinop(OpArrow, macro $v { "test" }, o), pos : Context.currentPos() }];
// creates: "public var json:StringMap<Dynamic> = ['test' => json];"
var nf:Field = {
name : "json",
doc : "docs",
meta : [],
access : [APublic],
kind : FVar(macro : haxe.ds.StringMap<Dynamic>, { expr : EArrayDecl(a), pos : Context.currentPos() } ),
pos : Context.currentPos()
};
fields.push(nf);
return fields;
// error: Arrays of mixed types...
}
如果不提前知道json的结构是什么,我能做些什么吗?
答案 0 :(得分:1)
您仍然可以通过构建中间untyped
表达式(更简单地为EUntyped(o)
)来使用macro untyped $o
。
或者,您可以遍历已解析的对象并将ECheckType
添加到Dynamic
表达式到每个数组,生成类似于([...]:Array<Dynamic>)
的内容。
在构建地图文字表达式之前,执行此操作看起来就像使用已解析的checkTypeArrays
对象调用以下o
函数。
static function checkTypeArrays(e:Expr):Expr
{
return switch (e) {
case { expr : EArrayDecl(vs), pos : pos }:
macro ($a{vs.map(checkTypeArrays)}:Array<Dynamic>);
case _:
haxe.macro.ExprTools.map(e, checkTypeArrays);
}
}
对此的改进是仅将(:Array<Dynamic>)
包裹在Context.typeof(expr)
失败的数组中。