Flutter升级后出现Null操作错误,如何处理模型类空值赋值?
我有一个用于解析API的模型类MovieDetail:
class MovieDetail { final int id; final bool adult; final int budget; final List<Genre> genres; final List<Company> companies; final String releaseDate; final int runtime; ...
以下是MovieDetailResponse的完整代码:
import 'movie_detail.dart'; class MovieDetailResponse { final MovieDetail movieDetail; final String error; MovieDetailResponse(this.movieDetail, this.error); MovieDetailResponse.fromJson(Map<String, dynamic> json) : movieDetail = MovieDetail.fromJson(json), error = ""; MovieDetailResponse.withError(String errorValue) : movieDetail = MovieDetail(null, null, null, null, null, "", null), error = errorValue; }
报错的具体代码段为:
MovieDetailResponse.withError(String errorValue) : movieDetail = MovieDetail(null, null, null, null, null, "", null), error = errorValue;
升级Flutter后出现如下错误日志:
The argument type 'Null' can't be assigned to the parameter type 'int'.
The argument type 'Null' can't be assigned to the parameter type 'bool'.
The argument type 'Null' can't be assigned to the parameter type 'int'.
The argument type 'Null' can't be assigned to the parameter type 'List'.
The argument type 'Null' can't be assigned to the parameter type 'List'.
The argument type 'Null' can't be assigned to the parameter type 'int'.
请问该如何正确定义空值以解决此问题?
这是Flutter启用空安全机制后引发的问题,原代码在空安全环境下无法将null赋值给非可空类型的参数,可通过以下两种方案解决:
方案一:将MovieDetail的字段改为可空类型
修改MovieDetail类,给所有非可空字段添加?标记,使其支持空值:
class MovieDetail { final int? id; final bool? adult; final int? budget; final List<Genre>? genres; final List<Company>? companies; final String releaseDate; // 若允许releaseDate为空,可改为String? final int? runtime; // 同步调整构造函数参数类型 MovieDetail(this.id, this.adult, this.budget, this.genres, this.companies, this.releaseDate, this.runtime); // fromJson方法需适配空值处理 factory MovieDetail.fromJson(Map<String, dynamic> json) { return MovieDetail( json['id'] as int?, json['adult'] as bool?, json['budget'] as int?, (json['genres'] as List?)?.map((e) => Genre.fromJson(e)).toList(), (json['companies'] as List?)?.map((e) => Company.fromJson(e)).toList(), json['release_date'] as String? ?? "", // 为空时赋予默认值 json['runtime'] as int? ); } }
修改后,withError构造函数即可正常传入null:
MovieDetailResponse.withError(String errorValue) : movieDetail = MovieDetail(null, null, null, null, null, "", null), error = errorValue;
方案二:将MovieDetailResponse的movieDetail字段设为可空
无需修改MovieDetail类,直接调整MovieDetailResponse的字段定义:
class MovieDetailResponse { final MovieDetail? movieDetail; // 添加?标记为可空类型 final String error; MovieDetailResponse(this.movieDetail, this.error); MovieDetailResponse.fromJson(Map<String, dynamic> json) : movieDetail = MovieDetail.fromJson(json), error = ""; MovieDetailResponse.withError(String errorValue) : movieDetail = null, // 直接赋值null error = errorValue; }
这种方案更符合业务逻辑:请求出错时本就不需要有效的MovieDetail实例,直接让该字段为null即可,避免创建全为空值的无效实例。
额外建议
如果使用json_serializable库生成JSON解析代码,可自动适配空安全规则,减少手动编码的错误。
内容的提问来源于stack exchange,提问作者1988

