我无法将
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
最好的方法是什么?我认为这可以通过迭代地图来完成,但如果这些非常大,这是一个昂贵的操作。有什么方法可以在不迭代的情况下投射它们吗?
我不相信在处理这样的嵌套数据时有办法转换为适当的类型。
这里有一个关于转换嵌套列表的类似讨论: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
}