未处理的异常:类型'String'不是'value'类型'List <String>'类型的子类型

时间:2020-03-23 19:10:48

标签: string exception dart

我完全困惑。我实质上是在尝试做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);
}

Click here and gaze in wonder on the bafflement

2 个答案:

答案 0 :(得分:0)

好的,现在我知道发生了什么。对象具有runtimeType,即使P具有未声明的类型声明MapP.runtimeType也可以是例如。 Map<String,List<String>>。一旦发生这种情况,Map就无法再存储异构对象。这对我来说很难解决,类型声明Map<String,dynamic> PMap<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的首次调用的输入中进行映射来解决此问题。