Flutter迁移空安全后snapshot.data.length相关报错如何解决?
报错原因
你遇到的两个报错是Dart空安全下的类型校验机制导致的:
- 第一个报错是
snapshot.data可能为null,空安全不允许直接访问可空类型的属性 - 你加了
!强制非空后出现的第二个报错,是因为你没有给FutureBuilder和异步方法指定明确的返回类型,Dart默认将snapshot.data推断为Object类型,而Object本身没有length属性。非空安全版本中Dart类型校验宽松,默认会当做dynamic处理,所以不会报错。
解决方案
按以下步骤修改即可:
- 第一步:修改
showAllPost方法,明确指定返回类型,同时补全异常分支的返回值
// 修改前是Future showAllPost() async Future<List<dynamic>> showAllPost() async { var url = "$baseUrl/searchPost.php"; var response = await http.post( Uri.parse(url), body: {'title': query}, ); if (response.statusCode == 200) { var jsonData = json.decode(response.body); print(jsonData); return jsonData as List<dynamic>; } // 非200状态返回空列表 return []; }
- 第二步:给
FutureBuilder指定泛型为List<dynamic>,明确snapshot.data的类型 - 第三步:访问
snapshot.data的属性时,除了加!强制非空,列表索引访问也要对应修改
@override Widget buildResults(BuildContext context) { // 这里加泛型 return FutureBuilder<List<dynamic>>( future: showAllPost(), builder: (context, snapshot) { if (snapshot.hasData) { return ListView.builder( // 现在snapshot.data已经是List类型,加!后可以正常访问length itemCount: snapshot.data!.length, itemBuilder: (context, index) { // 这里也要加! var list = snapshot.data![index]; // 后面的原有业务代码保持不变即可 return Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: <Widget>[ // 原有布局代码无需修改 ], ); }, ); } return CircularProgressIndicator(); }, ); }
如果想进一步提升代码健壮性,还可以给返回的列表元素定义数据模型类,把dynamic替换成具体的模型类,后续使用时不需要再做类型判断,代码可维护性更高。
内容的提问来源于stack exchange,提问作者Murali Krishnan
相关产品推荐
相关产品推荐

