类型“_InternalLinkedHashMap<String, dynamic>”不是类型转换中“Map<String, String>”类型的子类型

问题描述 投票:0回答:1

我无法将

Map<String, dynamic>
转换为
Map<String, Map<String, String>
。最好的方法是什么?

请注意,我正在使用我的

analysis_options.yaml
中的高级分析选项:

analyzer:
  enable-experiment:
    - extension-methods
  strong-mode:
    implicit-casts: false
    implicit-dynamic: false

我试过了

var de = Map<String, Map<String, String>>.from((json.decode(await rootBundle.loadString('lang/de.json'))) as Map<String, dynamic>);

var de = (json.decode(await rootBundle.loadString('lang/de.json')) as Map<String, dynamic>).cast<String, Map<String, String>>();

var de = Map.castFrom<String, dynamic, String, Map<String, String>>((json.decode(await rootBundle.loadString('lang/de.json'))) as Map<String, dynamic>);

所有尝试都会引发以下运行时错误:

type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Map<String, String>' in type cast

最好的方法是什么?我认为这可以通过迭代地图来完成,但如果这些非常大,这是一个昂贵的操作。有什么方法可以在不迭代的情况下投射它们吗?

flutter dart casting type-conversion
1个回答
3
投票

我不相信在处理这样的嵌套数据时有办法转换为适当的类型。

这里有一个关于转换嵌套列表的类似讨论:https://github.com/dart-lang/language/issues/1574

我认为以某种方式迭代数据是在这种情况下你唯一能做的事情。

一种可能的解决方案:

final data = await rootBundle.loadString('lang/de.json');
final Map<String, Map<String, String>> de = {
  for (final entry in (json.decode(data) as Map).entries)
    entry.key as String: {
      for (final e in (entry.value as Map).entries)
        e.key as String: e.value as String,
    },
};

dart 3.3 起,一种开销较小的潜在选择是在 json 对象上创建 extension type 包装器。

例如:

import 'dart:convert';

extension type LanguageMap(Map<String, dynamic> json) {
  TranslationMap? operator [](String s) => json[s] as TranslationMap?;
}

extension type TranslationMap(Map<String, dynamic> json) {
  String? operator [](String s) => json[s] as String?;
}

void main() {
  Map<String, dynamic> json = jsonDecode(
          '{ "english": {"hello": "Hello"}, "spanish": {"hello": "Hola"} }')
      as Map<String, dynamic>;

  final lang = LanguageMap(json);
  final String? result = lang['spanish']?['hello'];
  print(result); // Hola
}
© www.soinside.com 2019 - 2024. All rights reserved.