flutter - Dart - 复制像 kotlin 这样的密封类时出现问题
问题描述
我正在编写的起始示例中出现此错误
type 'Error<dynamic>' is not a subtype of type 'FutureOr<Success<List<TaskEntity>>>'
我创建了一个像这样的通用 Result 类:
enum DataStatus { local, remote, error }
enum ErrorStatus { unknown, backend_error, timeout }
@sealed
abstract class Result<T> {}
class Success<T> extends Result<T> {
final T data;
final DataStatus dataStatus;
final String message;
Success({this.data, this.dataStatus, this.message});
}
class Error extends Result {
final Exception exception;
final ErrorStatus errorStatus;
final String message;
Error({this.exception, this.errorStatus, this.message});
}
在我的存储库中,我有这个方法:
Future<Result<List<TaskEntity>>> getTasks() {
return remoteDataSource
.getTasks()
.then((value) => Success(
data: value.map((e) => e.toTaskEntity()).toList(),
dataStatus: DataStatus.remote))
.catchError((Object obj) {
switch (obj.runtimeType) {
case DioError:
final dioErrorResponse = (obj as DioError).response;
return Error(
exception: Exception(dioErrorResponse.statusMessage),
errorStatus: ErrorStatus.backend_error,
message: dioErrorResponse.statusMessage);
break;
default:
}
});
我的方法是使用此类返回响应,如果有错误则返回错误。
现在我被阻止了,因为我收到了这个错误
type 'Error<dynamic>' is not a subtype of type 'FutureOr<Success<List<TaskEntity>>>'
我也尝试使用冻结的库,但没有运气。
part 'result.freezed.dart';
@freezed
abstract class Result<T> with _$Result<T> {
const factory Result.success({T data, DataStatus dataStatus, String message}) = Success<T>;
const factory Result.error({Exception exception, ErrorStatus errorStatus, String message}) = Error;
}
解决方案
您的问题是您从未T
直接或隐含地为您的错误类指定 a 。所以它是一个Error<dynamic>
. 但 anError<dynamic>
不延伸Result<List<TaskEntity>>
。一个Error<List<TaskEntity>>
愿意。所以你需要确保你的 Error 类T
也有一个类型。
老实说,整件事.then
.catch
对我来说太复杂了。我会使用正常的async
/块。但如果你想保持原样,至少要确保你这样做:await
try
catch
return Error<List<TaskEntity>>(
所以你的Error<>
类在语法上是正确的类型。
就像我所说的通过使用async
and使其更容易的一个例子await
:
Future<Result<List<TaskEntity>>> getTasks() async {
try {
final results = await remoteDataSource.getTasks();
final tasks = results.map((e) => e.toTaskEntity()).toList()
return Success<List<TaskEntity>>(data: tasks, dataStatus: DataStatus.remote);
} catch (e) {
if (e is DioError) {
return Error<List<TaskEntity>>(
exception: Exception(e.response.statusMessage),
errorStatus: ErrorStatus.backend_error,
message: e.response.statusMessage);
} else {
// you are missing a case here? what do you want to return here?
}
}
}
对我来说,这更容易阅读,以至于很明显你错过了一个案例。那里需要有一个return
声明。
推荐阅读
- php - 单击文本后如何将值放入变量中
- javascript - 有没有办法在不禁用 swiper-prev 的情况下在最后一张幻灯片上启动 Swiper 滑块?
- swift - 如何快速将麦克风的输入转换为另一种格式?
- sql - 除了使用 psql 之外,还有其他将数据导入 Postgres 的方法吗?
- azure - Azure 数据工厂数据流中“数据集”和“内联”源之间的区别?
- mips - %hi 和 %lo 的 MIPS 错误
- express - 在 Google Cloud Run 上运行的 Express 服务器在响应 204 状态代码时返回 502 Bad Gateway
- android - setState 不会在颤动中刷新 ListView.builder
- java - 将字符串数组元素与文件夹中的文件名进行比较,如果匹配将它们移动到另一个文件夹
- javascript - express.static 不工作。无法获取图像