如何让Dart不将Map推断为<String, String>类型,而是保留为<String, dynamic>类型?
你遇到的报错是Dart的类型推断机制导致的:当Map字面量里所有值都是String类型时,Dart会自动将该Map推断为Map<String, String>类型,后续只能存入String类型的值,塞入其他类型就会抛出类型不匹配错误。
以下是不需要加冗余键值对的可行解决方案:
方案1:显式声明集合的完整类型
这是最推荐的做法,直接明确指定data的类型,绕过Dart的自动类型推断:
class MyClass { String ageGroup = 'some'; MyClass({required this.ageGroup}); } void main() { // 显式指定类型,禁止Dart按初始值自动收窄类型 List<Map<String, dynamic>> data = [ { 'name': 'john', 'userName': 'john', }, { 'name': 'john1', 'userName': 'john1', }, ]; print(data[0].runtimeType); // 赋值正常 data[0]['ageGroup'] = MyClass(ageGroup: 'something'); }
方案2:为首个Map字面量加类型标注
如果不想写完整的变量类型,只需要给列表里的第一个Map添加类型标注,Dart会自动将整个List的类型推断为List<Map<String, dynamic>>:
void main() { var data = [ // 仅给第一个Map加类型标注即可 <String, dynamic>{ 'name': 'john', 'userName': 'john', }, { 'name': 'john1', 'userName': 'john1', }, ]; data[0]['ageGroup'] = MyClass(ageGroup: 'something'); }
方案3:对已存在的String类型Map集合做转换
如果你的初始集合是从其他地方获取的、已经被推断为List<Map<String, String>>类型,可以逐个重构Map为Map<String, dynamic>类型:
void main() { // 假设这是从其他地方拿到的、已经被推断为List<Map<String, String>>的集合 var data = [ { 'name': 'john', 'userName': 'john', }, { 'name': 'john1', 'userName': 'john1', }, ]; // 逐个重构Map,替换原有的类型约束 final dynamicData = data.map((item) => Map<String, dynamic>.from(item)).toList(); dynamicData[0]['ageGroup'] = MyClass(ageGroup: 'something'); }
注意:你之前尝试的
cast()方法无效的原因是,cast仅会给原集合套一层类型伪装,内部的Map实际还是Map<String, String>类型,运行时赋值依然会触发类型校验错误,必须重新构造Map才能修改实际的类型约束。
内容的提问来源于stack exchange,提问作者Yash Patel
相关产品推荐
相关产品推荐

