基于Freezed的Dart可判别联合Result类型优化方案咨询
在Flutter/Dart中用Freezed实现类型安全的Result可判别联合方案
核心思路
通过Freezed的嵌套可判别联合结构,将Result分为明确的success/error根分支,同时把所有成功场景的子类型统一归到success分支的嵌套类型中,既满足场景细分需求,又从结构上避免类型误判,保证类型安全。
完整实现代码
首先确保你的pubspec.yaml已添加依赖:
dependencies: freezed_annotation: ^2.4.1 flutter: sdk: flutter dev_dependencies: build_runner: ^2.4.8 freezed: ^2.4.7
然后定义Result和嵌套的SuccessState类型:
import 'package:freezed_annotation/freezed_annotation.dart'; part 'result.freezed.dart'; // 根Result类型,仅区分success/error两大分支 @freezed class Result<T> with _$Result<T> { // success分支接收统一的SuccessState类型 const factory Result.success(SuccessState<T> state) = _Success<T>; // error分支可携带Exception或自定义错误信息 const factory Result.error(Exception exception) = _Error<T>; } // 统一的成功状态子类型,包含具体场景的细分 @freezed class SuccessState<T> with _$SuccessState<T> { // 带泛型数据的成功场景,适用于返回具体数据的请求 const factory SuccessState.value(T data) = SuccessValue<T>; // 仅带提示信息的成功场景,适用于无需返回数据的操作(如提交表单) const factory SuccessState.message(String message) = SuccessMessage; // 无数据无提示的成功场景,适用于静默操作(如删除) const factory SuccessState.empty() = SuccessEmpty; }
代码说明
- 层级结构约束:所有成功相关的子类型都属于
SuccessState,而Result.success仅接收SuccessState实例。开发者无法直接将SuccessValue/SuccessMessage作为Result的分支,从根源避免了类型误判。 - 泛型支持:
SuccessState.value<T>支持任意泛型类型,适配不同业务场景的数据返回需求(如列表、实体类等)。 - 类型安全保障:Freezed生成的
when/map方法会强制覆盖所有分支,处理Result时必须先处理success/error,再在success分支内处理具体的SuccessState子类型,不会出现遗漏或类型转换错误。
使用示例
// 创建不同状态的Result实例 final dataResult = Result.success(SuccessState.value<String>('用户列表数据')); final messageResult = Result.success(SuccessState.message('修改密码成功')); final emptyResult = Result.success(SuccessState.empty()); final errorResult = Result.error(Exception('请求超时,请重试')); // 处理Result状态 dataResult.when( success: (successState) { successState.when( value: (data) => print('成功获取数据:$data'), message: (msg) => print('操作提示:$msg'), empty: () => print('操作完成,无返回数据'), ); }, error: (exception) => print('请求错误:${exception.toString()}'), );
优化效果对比
- 原实现中
Success/SuccessValue等是平级的Result分支,开发者可能误将SuccessMessage当成SuccessValue处理;现在所有成功子类型都被包裹在SuccessState内,必须通过两层when处理,从结构上杜绝了此类错误。 - 泛型
SuccessValue<T>在使用时会自动推导类型,无需手动强制转换,进一步提升类型安全性。
内容的提问来源于stack exchange,提问作者WiseDev
相关产品推荐
相关产品推荐

