Необработанное исключение: тип 'String' не является подтипом типа 'List <String>' of 'value' - PullRequest
0 голосов
/ 23 марта 2020

Я полностью сбит с толку. По сути, я пытаюсь сделать foo["x"]="y" и получаю самые удивительные исключения. Я на самом деле сделал минимальный рабочий пример, и мне пришлось вкладывать Карты и Списки, чтобы что-то сломалось. Я понятия не имею, что происходит.

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);
}

Кликните здесь и с удивлением посмотрите на озадачение

Ответы [ 2 ]

0 голосов
/ 24 марта 2020

У вас проблемы с тем, что вы боретесь против системы типов в 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.

0 голосов
/ 23 марта 2020

ОК, теперь я понимаю, что происходит. Объекты имеют runtimeType, и хотя P имеет непритязательное объявление типа Map, P.runtimeType может быть, например, Map<String,List<String>>. Как только это произойдет, Map больше не сможет хранить гетерогенные объекты. Обойти это было довольно сложно для меня, объявления типов Map<String,dynamic> P или Map<String,Object> P действительно не помогают, нежелательные runtimeType могут остаться. Я подал это как «ошибка» , хотя, возможно, это будет считаться ошибкой.

Эта сущность имеет обходной путь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...