如何在Dart中实现类似Kotlin的泛型网络资源状态类?
Dart 实现网络请求状态密封类最佳实践
实现代码(适配 Dart 3.0+,支持泛型、密封限制、父类直接调用)
// 密封类限制,禁止外部随意继承扩展,保证状态可穷尽匹配 sealed class Resource<T> { final T? data; final String? error; // 私有构造,禁止外部直接实例化父类 Resource._({this.data, this.error}); // 静态构造方法,实现和Kotlin一致的 `Resource.success<T>()` 调用方式 static Resource<T> success<T>(T? data) => _Success<T>(data); static Resource<T> loading<T>() => _Loading<T>(); static Resource<T> error<T>(String error) => _Error<T>(error); } // 私有子类,对外不可见,只能通过Resource的静态方法创建 class _Success<T> extends Resource<T> { _Success(T? data) : super._(data: data); } class _Loading<T> extends Resource<T> { _Loading() : super._(); } class _Error<T> extends Resource<T> { _Error(String error) : super._(error: error); }
核心优化点
- 完全匹配Kotlin版本的调用习惯:创建实例时直接调用
Resource.success<User>(userData)、Resource.loading<HomeInfo>()、Resource.error<String>("网络请求失败"),不需要单独引入子类 - 全程保留泛型类型,避免原有代码中用
dynamic丢失类型安全的问题 - 基于Dart 3 sealed特性实现密封限制,配合模式匹配可以做穷尽判断,和Kotlin的when表达式用法完全一致
- 子类私有化,外部无法随意创建未知状态类,保证状态的可控性
使用示例
// 处理请求状态 void handleResource(Resource<User> res) { switch (res) { case _Success<User>(data: final user): print("请求成功,用户名为${user?.name}"); case _Loading<User>(): print("加载中"); case _Error<User>(error: final err): print("请求失败:$err"); } }
兼容 Dart 2.x 版本实现
如果你的项目还没升级到Dart 3,去掉sealed修饰符即可使用,只是无法享受编译期穷尽匹配的检查:
abstract class Resource<T> { final T? data; final String? error; Resource._({this.data, this.error}); static Resource<T> success<T>(T? data) => _Success<T>(data); static Resource<T> loading<T>() => _Loading<T>(); static Resource<T> error<T>(String error) => _Error<T>(error); } class _Success<T> extends Resource<T> { _Success(T? data) : super._(data: data); } class _Loading<T> extends Resource<T> { _Loading() : super._(); } class _Error<T> extends Resource<T> { _Error(String error) : super._(error: error); }
内容的提问来源于stack exchange,提问作者Mena
相关产品推荐
相关产品推荐

