You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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;
}

代码说明

  1. 层级结构约束:所有成功相关的子类型都属于SuccessState,而Result.success仅接收SuccessState实例。开发者无法直接将SuccessValue/SuccessMessage作为Result的分支,从根源避免了类型误判。
  2. 泛型支持:SuccessState.value<T>支持任意泛型类型,适配不同业务场景的数据返回需求(如列表、实体类等)。
  3. 类型安全保障: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 20:55:06