Flutter调用API时如何处理空安全相关的变量未赋值报错
问题原因
Dart空安全机制要求非空类型的局部变量,必须在所有可能的执行路径上完成赋值后才可以使用。你之前只给变量加?修饰没有生效,是因为方法的返回类型定义为不可空的Future<LoginResponseModel>,即便把model改成可空类型,返回时可空类型和不可空的返回值类型不匹配,依然会触发校验报错。
可行解决方案
下面给三种常用的处理方案,你可以根据业务场景选择:
方案1:调整返回类型为可空(最简便)
如果业务允许接口请求失败时返回空,直接同步修改返回类型和变量的可空标识即可:
// 返回类型改为可空 Future<LoginResponseModel?> loginCustomer( String username, String password) async { // 变量声明为可空 LoginResponseModel? model; try { var response = await Dio().post(Config.tokenURL, data: { "username": username, "password": password, }, options: Options(headers: { HttpHeaders.contentTypeHeader: "application/x-www-form-urlencoded", })); if (response.statusCode == 200) { model = LoginResponseModel.fromJson(response.data); } } on DioError catch (e) { print(e.message); } return model; }
上层调用时判断返回值是否为空,再做后续逻辑处理即可。
方案2:异常分支抛出错误(推荐用于严格业务场景)
如果业务不允许返回空值,那就在所有无法正常赋值model的分支抛出异常,让上层调用方通过try-catch处理异常场景,这样不会走到return model的逻辑,自然不会触发未赋值的报错:
Future<LoginResponseModel> loginCustomer( String username, String password) async { // 用late修饰表示后续会完成赋值 late LoginResponseModel model; try { var response = await Dio().post(Config.tokenURL, data: { "username": username, "password": password, }, options: Options(headers: { HttpHeaders.contentTypeHeader: "application/x-www-form-urlencoded", })); if (response.statusCode == 200) { model = LoginResponseModel.fromJson(response.data); } else { // 状态码不符合要求时抛出异常 throw Exception("接口请求异常,状态码:${response.statusCode}"); } } on DioError catch (e) { print(e.message); // 捕获到Dio异常后重新抛出给上层处理 rethrow; } return model; }
方案3:设置默认返回值(仅适合有明确默认业务模型的场景)
如果你的业务有明确的默认失败响应模型,可以直接给model初始化一个默认值,保证所有路径都有值返回:
Future<LoginResponseModel> loginCustomer( String username, String password) async { // 初始化默认失败的响应模型,参数根据你自己的实体类结构调整 LoginResponseModel model = LoginResponseModel(code: -1, msg: "请求失败"); try { var response = await Dio().post(Config.tokenURL, data: { "username": username, "password": password, }, options: Options(headers: { HttpHeaders.contentTypeHeader: "application/x-www-form-urlencoded", })); if (response.statusCode == 200) { model = LoginResponseModel.fromJson(response.data); } } on DioError catch (e) { print(e.message); } return model; }
内容的提问来源于stack exchange,提问作者naveen
相关产品推荐
相关产品推荐

