我完全困惑。我实质上是在尝试做foo["x"]="y"
并获得最令人困惑的异常。实际上,我做了一个最小的工作示例,并且不得不嵌套Maps和Lists才能使事情中断。我不知道发生了什么。
Map fixprobset(Map P) {
print(P);
if(!P.containsKey("name")) {
final foo = P["tileset"].join(" ");
P["name"] = foo;
}
if(P.containsKey("children")) {
for(var k=0; k<P["children"].length;k++) fixprobset(P["children"][k]);
}
return P;
}
void main() {
Map problemset = fixprobset({
"name": "Jingle Jangle",
"children": [
{
"tileset": ["1","2","3"]
}
]
});
print(problemset);
}
答案 0 :(得分:0)
好的,现在我知道发生了什么。对象具有runtimeType
,即使P
具有未声明的类型声明Map
,P.runtimeType
也可以是例如。 Map<String,List<String>>
。一旦发生这种情况,Map
就无法再存储异构对象。这对我来说很难解决,类型声明Map<String,dynamic> P
或Map<String,Object> P
确实无济于事,不受欢迎的runtimeType
仍然存在。我已将其作为"bug"提交,尽管也许它会被视为(错误)功能。
此gist具有解决方法。
答案 1 :(得分:0)
您遇到的问题来自与Dart中的类型系统作斗争的事实。您已经发现,关于runtimeType的某些内容似乎会自动分配给dynamic
以外的其他类型。
我已经制作了可以正常工作的示例:
Map fixprobset(Map<dynamic, dynamic> P) {
print(P);
if (!P.containsKey("name")) {
final foo = (P["tileset"] as List).join(" ");
P["name"] = foo;
}
if (P.containsKey("children")) {
for (var k = 0; k < (P["children"] as List).length; k++) {
fixprobset((P["children"] as List)[k] as Map);
}
}
return P;
}
void main() {
final problemset = fixprobset(<dynamic, dynamic>{
"name": "Jingle Jangle",
"children": <dynamic>[
<dynamic, dynamic>{
"tileset": <dynamic>["1", "2", "3"]
}
]
});
print(problemset);
}
如您所见,自动分配的类型来自您的输入数据,这些数据会在程序开始时得到分配的类型。那么您的问题是,您不希望这种自动分配的类型,而是想要在创建后更改它们。因此,您想将List<String>
更改为List<dynamic>
,但是要创建一个新的对象,因为您不能在创建对象后更改其类型。
因此,我的“解决方案”通过在创建列表时设置类型并在对fixprobset
的首次调用的输入中进行映射来解决此问题。