Dart空安全下枚举如何设置默认非空返回值?
枚举映射非空返回的实现方案
报错根因
空安全开启后,Dart 中Map的[]操作符返回值类型为可空的int?——即便你已经为当前枚举的所有取值配置了映射关系,静态类型检查也无法100%保证Map查找结果一定非空,因此直接将查找结果赋值给返回类型为非空int的getter时,就会触发类型不匹配的编译报错。
你提出的“让statusCode getter返回默认非空值、后续无需额外处理空值”的需求完全可行,不存在语法层面的限制,可以根据当前Flutter版本选择对应的实现方式:
适配当前Flutter 2.0.1版本的实现(空合并运算符兜底)
只需要在Map查找结果后追加空合并运算符??,指定一个合理的默认值即可完成改动:
enum LoginType { PHONE, WECHAT } extension ResponseStatusExtension on LoginType{ static const statusCodes = { LoginType.PHONE: 1, LoginType.WECHAT: 2, }; // 当Map查找返回null时,自动返回默认值0,可按需调整默认取值 int get statusCode => statusCodes[this] ?? 0; }
这种写法改动量极小,最终getter的返回值是明确的非空int类型,后续业务代码调用时不需要做任何空值判断,完全满足你提出的健壮性要求。
高版本Dart下的更优实现(穷尽switch)
注意:该写法需要Dart 3.0及以上版本支持,当前Flutter 2.0.1对应Dart 2.12版本暂不支持,可作为后续版本升级后的优化方案
如果你不想硬编码默认兜底值,同时希望后续新增枚举成员时能在编译阶段就发现未配置映射的问题,可以使用穷尽switch表达式实现映射。这种写法不需要额外指定默认值,因为枚举的所有取值都被分支覆盖,静态检查会自动推导结果为非空int:
int get statusCode => switch(this) { LoginType.PHONE => 1, LoginType.WECHAT => 2, };
这种写法的健壮性更强:后续如果新增了LoginType的枚举成员,却没有在switch里补充分支,编译器会直接抛出报错,避免运行时才出现映射缺失的隐蔽问题。
内容的提问来源于stack exchange,提问作者Dolphin
相关产品推荐
相关产品推荐

