Flutter/Dart缓存快照值引用问题:类型不匹配错误修复
问题修复方案
错误根源
触发type 'String' is not a subtype of type 'int' of 'index'的核心原因:
- 缓存的
cache4存储的是Map转成的字符串列表,但使用时未将字符串反序列化回Map,导致用原始字符串去匹配ListNode的code字段(或错误地将字符串当作数组索引使用)。 Code字段类型不匹配:如果ListNode的code是int类型,而缓存字符串中Code以字符串形式存储,直接对比会引发类型错误。
修复步骤及代码示例
1. 读取缓存时反序列化字符串为Map
在FutureBuilder中,将缓存的每个字符串通过jsonDecode()转回原始Map结构:
import 'dart:convert'; // ... FutureBuilder<List<String>>( future: getCache4(), // 获取缓存的字符串列表 builder: (context, snapshot) { if (snapshot.hasData && snapshot.data!.isNotEmpty) { return ListView.builder( itemCount: snapshot.data!.length, itemBuilder: (context, index) { // 将字符串反序列化为Map final incidentMap = jsonDecode(snapshot.data![index]) as Map<String, dynamic>; final itemCode = incidentMap['Code'].toString(); return ListTile( title: Text(itemCode), onTap: () async { // 调用接口获取LossEvent数据 final lossEventData = await fetchLossEvent(); // 匹配对应run_hyperlink try { final targetNode = lossEventData.listNode.firstWhere( // 显式转换类型后匹配(假设ListNode的code是int类型) (node) => node.code == int.parse(itemCode), orElse: () => throw StateError("无匹配节点"), ); final hyperlink = targetNode.run_hyperlink; // 后续处理hyperlink逻辑 } catch (e) { print(e.toString()); } }, ); }, ); } return const Center(child: CircularProgressIndicator()); }, );
2. 优化缓存存储方式(可选)
如果可以修改缓存逻辑,建议直接存储序列化后的整个列表字符串,而非单个Map转字符串的列表:
- 缓存时:
// incidentList是原始的Map列表 final cacheStr = jsonEncode(incidentList); await saveToCache4(cacheStr);
- 读取时:
Future<List<Map<String, dynamic>>> getCache4() async { final cacheStr = await readFromCache4(); return jsonDecode(cacheStr) as List<Map<String, dynamic>>; }
这种方式能避免逐个反序列化的麻烦,也减少类型错误概率。
关键注意点
- 必须保证缓存时是用
jsonEncode()将Map转为字符串,否则jsonDecode()会报错。 - 明确
Code字段的类型:如果接口返回的ListNode.code是int,必须将缓存中的字符串类型Code转为int后再对比;如果是字符串类型,直接对比即可。 - 避免将字符串当作数组索引使用:检查代码中是否有类似
list['someString']的写法,数组索引必须是int类型。
内容的提问来源于stack exchange,提问作者JoshuaaMarkk
相关产品推荐
相关产品推荐

