Flutter/Dart中向Map添加嵌套Map报错及页面传参问题排查
问题分析与解决
初始Map添加嵌套Map报错的原因
你定义的var a = {'field1':'one','field2':'two'},Dart会自动推断这个Map的类型为Map<String, String>——因为所有值都是String类型。当你试图给它添加一个嵌套Map(属于Map<String, dynamic>类型)时,就会出现类型不匹配的错误,因为Map不能被赋值给String?类型的value。
解决方法
显式指定Map的类型为Map<String, dynamic>,让它可以容纳String、嵌套Map等多种类型的值:
// 方式1:直接声明类型 Map<String, dynamic> a = { 'field1' : 'one', 'field2' : 'two' }; // 方式2:使用类型字面量推断 var a = <String, dynamic>{ 'field1' : 'one', 'field2' : 'two' };
之后再执行添加嵌套Map的代码就不会报错了:
a['b'] = { 'nestedKey':{ 'field1' : 'one' } };
页面传参场景的问题解决
同样是类型推断导致的问题:你传参时的{'oldfield': 'old'}被Dart推断为Map<String, String>,而在ScreenB里你试图给它添加一个嵌套Map(非String类型),引发类型不兼容错误。另外你代码里的print($args)是语法错误,需改为print(args)。
解决方法
有两种可行的修正方式:
方式1:传参时显式指定Map类型
在跳转到ScreenB时,把args的Map指定为Map<String, dynamic>类型:
Navigator.of(context).pushAndRemoveUntil( MaterialPageRoute( builder: (context) => ScreenB( args: <String, dynamic>{ 'oldfield': 'old' }, )), (Route<dynamic> route) => false);
方式2:在ScreenB中指定args的类型
修改ScreenB的代码,将args的类型声明为Map<String, dynamic>,同时确保传参时的Map类型兼容:
import 'package:flutter/material.dart'; class ScreenB extends StatelessWidget { // 显式指定类型 final Map<String, dynamic> args; const ScreenB({Key? key, required this.args}) : super(key: key); @override Widget build(BuildContext context) { args['newfield'] ={ 'nested':{ 'field1' : 'one' } }; print(args); return Container(); } }
内容的提问来源于stack exchange,提问作者dontknowhy
相关产品推荐
相关产品推荐

