如何在纯Dart中实现Freezed Union的模式匹配?
在纯Dart中复现Freezed Union的模式匹配功能
当然可以通过手动实现抽象基类+子类的方式,在纯Dart中复现Freezed Union的模式匹配能力。核心思路是:
- 定义抽象基类,包含用于模式匹配的
when方法 - 为每个Union分支创建对应的子类,实现
when方法来分发到对应的处理逻辑 - 可选:给基类添加工厂构造器,让调用方式和Freezed保持一致
完整实现代码
// 抽象基类,定义模式匹配的when方法 abstract class Union { const Union(); // 工厂构造器,和Freezed的调用方式对齐 factory Union(int value) = Data; factory Union.loading() = Loading; factory Union.error([String? message]) = ErrorDetails; // 泛型when方法,接收各分支的处理函数 T when<T>( T Function(int value) data, T Function() loading, T Function(String? message) error, ); } // Data分支子类 class Data extends Union { final int value; const Data(this.value); @override T when<T>( T Function(int value) data, T Function() loading, T Function(String? message) error, ) { return data(value); } } // Loading分支子类 class Loading extends Union { const Loading(); @override T when<T>( T Function(int value) data, T Function() loading, T Function(String? message) error, ) { return loading(); } } // Error分支子类 class ErrorDetails extends Union { final String? message; const ErrorDetails([this.message]); @override T when<T>( T Function(int value) data, T Function() loading, T Function(String? message) error, ) { return error(message); } }
使用示例
void main() { var union = Union(42); print( union.when( (int value) => 'Data $value', loading: () => 'loading', error: (String? message) => 'Error: $message', ), ); // 输出: Data 42 union = Union.loading(); print( union.when( (value) => 'Data $value', loading: () => 'loading', error: (message) => 'Error: $message', ), ); // 输出: loading union = Union.error('请求失败'); print( union.when( (value) => 'Data $value', loading: () => 'loading', error: (message) => 'Error: $message', ), ); // 输出: Error: 请求失败 }
优缺点说明
- 优点:完全基于纯Dart实现,无需依赖任何代码生成工具,逻辑清晰可控。
- 缺点:需要手动维护每个子类的
when方法实现,当新增Union分支时,必须修改基类的when方法签名,并更新所有子类的实现,不像Freezed能自动生成代码减少重复劳动。
内容的提问来源于stack exchange,提问作者rubStackOverflow
相关产品推荐
相关产品推荐

