Dart桌面应用JSON转对象列表触发_CastError的解决方案咨询
Dart JSON解析CastError问题修复方案
核心异常触发原因
你代码中的map回调逻辑存在参数传错的问题:
// 错误写法 List<dynamic> liste = List<dynamic>.from(l.map((e) => Tablo.fromJson(cont)));
这里你将整个文件的字符串内容cont传入了Tablo.fromJson,而非遍历到的单个JSON对象e。cont是完整的JSON文件字符串,Tablo.fromJson内部执行json['id']时,相当于对字符串做索引取值,而字符串的[]操作符要求传入int类型索引,你传入了字符串类型的键'id',Dart会尝试做类型转换,最终触发type 'String' is not a subtype of type 'int' in type cast异常。
其他潜在问题
- 列表元素移除逻辑错误:正序遍历列表时删除元素会导致索引错位,出现漏删元素的情况
Tablo类未重写==和hashCode:默认的相等判断为对象引用比对,哪怕属性完全一致,不同实例也无法匹配,移除逻辑永远不会生效- 未处理空文件/文件不存在的场景,会直接抛出文件读取异常
- 同步IO操作会阻塞桌面应用主线程,造成界面卡顿
修复后的完整代码
修改后的Tablo类
class Tablo { final String tId; final String tobloIsim; Tablo(this.tId, this.tobloIsim); factory Tablo.fromJson(dynamic json) { return Tablo(json['id'] as String, json['projeAdi'] as String); } Map<String, dynamic> toJson() => { 'id': tId, 'projeAdi': tobloIsim, }; // 按属性重写相等判断,替代默认的引用比对 @override bool operator ==(Object other) => identical(this, other) || other is Tablo && runtimeType == other.runtimeType && tId == other.tId && tobloIsim == other.tobloIsim; @override int get hashCode => tId.hashCode ^ tobloIsim.hashCode; }
修改后的removeJson函数
Future<void> removeJson(Tablo silinecekTablo) async { final file = File("tablolar.json"); // 处理文件不存在的场景 if (!await file.exists()) return; String cont = await file.readAsString(); // 处理空文件场景 if (cont.isEmpty) return; List<dynamic> l = jsonDecode(cont); // 修正map回调参数,传入单个JSON对象e List<Tablo> liste = l.map((e) => Tablo.fromJson(e)).toList(); // 用removeWhere替代手动循环,避免索引错位 liste.removeWhere((tablo) => tablo == silinecekTablo); String yeniTablo = jsonEncode(liste); await file.writeAsString(yeniTablo); print("Silindi: ${liste.toString()}"); }
修改说明
- 修正
map回调的传入参数,从根源解决类型转换异常 fromJson中增加as String显式类型断言,提前规避类型不匹配问题- 重写
==和hashCode,保证属性一致的Tablo实例可以正常匹配 - 用
removeWhere替代手动for循环删除,避免索引错位漏删 - 增加文件存在、内容为空的前置判断,避免读取时报错
- 将同步IO改为异步操作,避免阻塞应用主线程
内容的提问来源于stack exchange,提问作者GloryX Game
相关产品推荐
相关产品推荐

