构建宏中的数组类型问题
Array typing issue in build macro
注意:我的问题 #4417 已关闭,但我不想成为那个为同一件事打开另一个问题的人。
基于 #3132,[ { "a": 1, "b": 2 }, { "a": 2 } ]
不会编译,除非您专门将其键入 Array<Dynamic>
或包含两者的任何类型。我想这很好,但是在下面的构建宏中,我没有地方可以输入数组,我得到了一个错误。
一般来说,我可以使用 untyped
(http://try.haxe.org/#3dBf5) 使地图文字符号工作,但我不能在这里这样做,因为我的类型还没有构建。
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 的结构是什么的情况下,我能做些什么吗?
您仍然可以通过构造一个中间 EUntyped(o)
表达式(更简单地说 macro untyped $o
)来使用 untyped
。
或者,您可以遍历已解析的对象并将 ECheckType
到 Dynamic
表达式添加到每个数组,生成类似 ([...]:Array<Dynamic>)
.
的内容
在构建地图字面量表达式之前,此方法的实现类似于使用已解析的 o
对象调用以下 checkTypeArrays
函数。
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)
.
中
注意:我的问题 #4417 已关闭,但我不想成为那个为同一件事打开另一个问题的人。
基于 #3132,[ { "a": 1, "b": 2 }, { "a": 2 } ]
不会编译,除非您专门将其键入 Array<Dynamic>
或包含两者的任何类型。我想这很好,但是在下面的构建宏中,我没有地方可以输入数组,我得到了一个错误。
一般来说,我可以使用 untyped
(http://try.haxe.org/#3dBf5) 使地图文字符号工作,但我不能在这里这样做,因为我的类型还没有构建。
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 的结构是什么的情况下,我能做些什么吗?
您仍然可以通过构造一个中间 EUntyped(o)
表达式(更简单地说 macro untyped $o
)来使用 untyped
。
或者,您可以遍历已解析的对象并将 ECheckType
到 Dynamic
表达式添加到每个数组,生成类似 ([...]:Array<Dynamic>)
.
在构建地图字面量表达式之前,此方法的实现类似于使用已解析的 o
对象调用以下 checkTypeArrays
函数。
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)
.