Не могли бы вы объяснить этот код синтаксического анализа dart json, пожалуйста?

#android #json #android-studio #flutter #dart

#Android #json #android-studio #флаттер #dart

Вопрос:

Итак, у меня есть этот код, который каким-то образом работает, однако я не могу объяснить, почему. Чтобы получить этот код, я использовал автоматический json для кодирования приложения под названием quicktype, используя в качестве входных данных json, который предоставляет моя компания. Целью кода является получение карты, содержащей полигоны в этом формате: {(Случайный идентификатор полигона)} ==> [Широта, долгота]

 class Poligoni {
  Map<String, List<String>> poligoni;
  Poligoni({
    this.poligoni,
  });
  factory Poligoni.fromRawJson(String str) {
    return Poligoni.fromJson(json.decode(str));
  }

  factory Poligoni.fromJson(Map<String, dynamic> json) {
    return Poligoni(
      poligoni: Map.from(json["Poligoni"]).map((k, v) {
        return MapEntry<String, List<String>>(
            k, List<String>.from(v.map((x) => x)));
      }),
    );
  }
}
 

Таким образом, код либо принимает необработанный json из функции (.fromRawJson), либо декодированный из функции (.FromJSON) . Здесь проблем нет. Часть, которая меня смущает, это :

 factory Poligoni.fromJson(Map<String, dynamic> json) {
    return Poligoni(
      poligoni: Map.from(json["Poligoni"]).map((k, v) {
        return MapEntry<String, List<String>>(
            k, List<String>.from(v.map((x) => x)));
      }),
    );
  }
 

Проблемы, с которыми я сталкиваюсь, заключаются в следующем (функция .FromJSON):

  1. Почему я возвращаю класс? пример: return Poligoni(.....various code)
  2. Использование конструктора перенаправления в данном случае мне не очень понятно poligoni:
  3. После этого возникает много трудностей с расшифровкой функции poligoni: : я знаю, что функция анализирует ключ json ‘Poligoni’ и преобразует его в другую карту типа, <String>,List<String> которая содержит для каждого ключа список точек, которые образуют многоугольник, однако я не уверен, как, если вы можете написать пошаговую инструкциюс благодарностью или в качестве альтернативы, если вы сможете переформатировать этот код, чтобы сделать его более понятным.

Я попытался просмотреть документы dart и flutter, но я не понял большую часть из них из-за вложенных функций, которые использует мой код, и небольшого языкового барьера.

Любая помощь очень ценится, с наилучшими пожеланиями.


Ответ №1:

Почему я возвращаю класс? пример: возврат Poligoni (….. различный код)

Потому что вы используете фабричный конструктор. Конструктор factory похож на статический метод, но ваш должен возвращать экземпляр объекта, совместимый с классом, частью которого он является.

Одним из преимуществ этого шаблона является то, что при использовании обычного конструктора вам не разрешается устанавливать какие-либо конечные переменные внутри тела конструктора, но их необходимо установить как часть фазы инициализации.

В вашем случае это действительно не проблема, поскольку переменной Map<String, List<String>> poligoni нет final , но она все равно может быть хорошим шаблоном.

Подробнее о конструкторах factory читайте здесь: https://dart.dev/guides/language/language-tour#factory-constructors

Использование конструктора перенаправления в не очень понятном в данном случае для меня полигоне:

Смотрите мой предыдущий ответ.

Очень сложно разобраться с функцией после poligoni :: я знаю, что функция анализирует ключ json ‘Poligoni’ и преобразует его в другую карту типа List, которая содержит для каждого ключа список точек, которые образуют многоугольник, однако я не уверен, как, если вы можете написать шаг -пошаговое прохождение по нему будет с благодарностью или в качестве альтернативы, если вы сможете переформатировать этот код, чтобы сделать его более понятным.

 factory Poligoni.fromJson(Map<String, dynamic> json) {
    return Poligoni(
      poligoni: Map.from(json["Poligoni"]).map((k, v) {
        return MapEntry<String, List<String>>(
            k, List<String>.from(v.map((x) => x)));
      }),
    );
  }
 

Как указывалось ранее, мы определили конструктор factory, который должен возвращать объект, совместимый с классом, частью которого он является. Поэтому в этом случае мы создаем новый Poligoni объект, вызывая конструктор Poligoni , который принимает именованный аргумент poligoni . Вот почему у нас есть poligoni: .

Мы устанавливаем именованный аргумент poligoni в значение следующего оператора:

 Map.from(json["Poligoni"]).map((k, v) {
        return MapEntry<String, List<String>>(
            k, List<String>.from(v.map((x) => x)));
      })
 

Я не совсем уверен, почему мы используем Map.from , но цель этого конструктора — создать новую карту на основе значений ключей из другой карты:
https://api.dart.dev/stable/2.10.4/dart-core/Map/Map.from.html

(лично я бы использовал приведение типов из json["Poligoni"] , поскольку это должен быть Map экземпляр)

Затем мы вызываем .map this new Map для создания другого нового Map , но где каждая пара ключ-значение сопоставляется с новыми парами ключ-значение следующим методом:

 (k, v) {
        return MapEntry<String, List<String>>(
            k, List<String>.from(v.map((x) => x)));
      }
 

Мы видим, что здесь мы сохраняем исходный ключ k , но преобразуем значение v с помощью:

 List<String>.from(v.map((x) => x))
 

Я предполагаю, что v это List<dynamic> так, и мы хотим создать новый список типа List<String> , взяв каждый элемент списка v и вставив его в новый список, который был определен как List<String> с самого начала.

Результат этого затем используется как значение в нашем новом Map , которое затем используется как значение для poligoni аргумента.

Короче говоря, все эти операции действительно используются для того, чтобы сделать ваш код более безопасным для типов путем преобразования dynamic типов в статически определенные типы.