我目前正在试验颤振框架和飞镖,偶然发现了一种看上去很奇怪的行为,我无法理解。尽管实际问题发生的环境要复杂得多,但我甚至能够在一个极其简化的展示中复制它:
Stream<Either<String, int>> result1 = Stream.fromIterable([1, 2, 3, 4, 5])
.map((number) => number < 4 ? Right(1) : Left('error'))
.onErrorReturnWith((error) => Left('error'));虽然上面的示例编译没有矛盾,但我确实得到了以下示例的编译错误:
错误:不能将'Left‘类型的值分配给'Right’类型的变量
Stream<Either<String, int>> result2 = Stream.fromIterable([1, 2, 3, 4, 5])
.map((number) => Right(1))
.onErrorReturnWith((error) => Left('error'));有谁能对这种方式有所了解吗?
########################################################
另一个例子是:
Future<Either<String, int>> someWebCall() {
Future<int> response = Future.delayed(Duration(milliseconds: 200), () {
throw SocketException('Well... ...it happens you know...');
});
return response.then((number) {
return number > 50.0 ? Right(number) : Left('number is too small...');
}).catchError((error) {
return Left('are you already questioning the meaning of your life?');
});}
这将编译但以运行时错误结尾:类型“未来”不是“Future>”类型的子类型
然后,我尝试给编译器尽可能多的提示,我想出这样的方法:
Future<Either<String, int>> someWebCall() {
Future<int> response = Future.delayed(Duration(milliseconds: 200), () {
throw SocketException('Well... ...it happens you know...');
});
return response.then<Either<String, int>>((number) {
return number > 50.0 ? Right(number) : Left('number is too small...') as Either<String, int>;
}).catchError((error) {
return Left('are you already questioning the meaning of your life?') as Either<String, int>;
});}
现在我得到了:类型'Left‘不是类型Either的子类型
我真的不能相信这件事
发布于 2020-09-26 19:51:10
函数(number) => Right(1)的类型是Right<dynamic, int> Function(int),这意味着map调用的结果流是Stream<Right<dynamic, int>>。
onErrorReturnWith需要返回与其调用的流的元素类型相同的内容,但它返回的是Left<String, dynamic>,而不是Right<dynamic, int>。
最简单的解决方法是告诉map调用返回哪种类型:
...
.map<Either<String, int>>( .... )然后,类型应该是您所期望的(而不是像第一个可能推断的示例那样的Either<dynamic, dynamic> )。
发布于 2020-09-27 06:47:09
我终于明白了通过潜入达茨的类型会发生什么。问题是编译器无法在只使用左或右的上下文中推断这两种类型的类型。也就是说,编译器可以将左边的部分推断为字符串,而在右边(5),编译器可以推断两者中任何一个的右部分为int。然而,他无法分别找出另一部分。使用下面的代码可以作为缩进。
Future<Either<String, int>> someWebCall() {
Future<int> response = Future.delayed(Duration(milliseconds: 200), () {
throw SocketException('Well... ...it happens you know...');
});
return response.then((number) {
return number > 50.0 ? Right(number) : Left('number is too small...');
}).catchError((error) {
return Left<String, int>('are you already questioning the meaning of your life?');
});https://stackoverflow.com/questions/64080552
复制相似问题