为什么直接使用泛型值是不可能的,但如果从 Dart 中的方法返回也是可能的
Why direct usage of generic value is not possible but same is possible if returned from method in Dart
为什么在直接赋值时无法为通用字段赋值,但在使用变量引用或方法时却可以return值(这里,相同的值赋给变量和方法 return 值相同)?
class User {}
class Teacher extends User {}
class Student extends User {}
Future<User> getUser() {
return Future.value(Student());
}
void main() {
Future<Future<User>> fut = Future.value(getUser()); // <----- No error
Future<Future<User>> fut2 = Future.value(Future.value(Student())); // <----- Getting error
Future<User> userFut3 = Future.value(Student());
Future<Future<User>> fut3 = Future.value(userFut3); // <----- No error
}
直接分配 Future.value(Future.value(Student()))
时出现以下错误。
Error: The argument type 'Student' can't be assigned to the parameter type 'FutureOr<Future<User>>?'.
因为在函数中你定义了 return 类型并且 dart 知道 return 类型,但是当直接赋值时 dart 不知道 Future.value(Student())
有一个 Future<User>
类型].要解决此问题,您必须告诉飞镖值的类型,如下所示:Future.value((Future.value(Student())) as Future<User>);
这样 dart 就会知道这个值的类型并将其视为 Future<User>
.
这里的问题是 Future<T>.value
的参数具有类型 FutureOr<T>
。它可以是未来或价值。
此外,Dart 类型推断的工作原理是“下推”上下文类型,然后尝试使表达式在该类型上工作,最后将最终的静态类型向上推。
如果像 Future.value(...)
这样的表达式具有上下文类型,则始终从上下文类型推断缺少的类型参数。
写的时候
Future<Future<User>> fut2 = Future.value(Future.value(Student()));
外部Future.value
的上下文类型,我们知道它应该有的类型是Future<Future<User>>
。这使得它的参数具有上下文类型 FutureOr<Future<User>>
。
参数是 Future.value(Student())
,我们对 Student()
还一无所知,因为我们还没有在类型推断中得到它,我们仍在朝着它努力。
一个Future<X>
可以通过两种方式满足FutureOr<Future<User>>
,要么是Future<User>
,要么是Future<Future<User>>
。
类型推断然后猜测是后者。这是错误的,但它还看不到。类型推断的工作方式,当有上下文类型时它必须使用上下文类型,但上下文类型不明确,最终选择了错误的选项。
您遇到了类型推断的边缘情况,其中可以通过两种不同的方式满足上下文类型,而向下类型推断选择了错误的方式。这是一个很好的启发式方法,如果你有一个 FutureOr<...>
上下文类型,并且你看到一个 Future
构造函数,你需要 FutureOr<...>
的 Future
部分。当你有 FutureOr<Future<...>>
时它就会崩溃。所以,不要那样做!
总的来说,我的建议是 永远不要 在您的程序中包含 Future<Future<anything>>
。它不仅避免了此类问题,而且还是您代码的更好模型。
一个最终完成到最终完成到某个值的东西的未来……只是让它最终直接完成到那个值。等待中间的未来只是无谓的忙碌
为什么在直接赋值时无法为通用字段赋值,但在使用变量引用或方法时却可以return值(这里,相同的值赋给变量和方法 return 值相同)?
class User {}
class Teacher extends User {}
class Student extends User {}
Future<User> getUser() {
return Future.value(Student());
}
void main() {
Future<Future<User>> fut = Future.value(getUser()); // <----- No error
Future<Future<User>> fut2 = Future.value(Future.value(Student())); // <----- Getting error
Future<User> userFut3 = Future.value(Student());
Future<Future<User>> fut3 = Future.value(userFut3); // <----- No error
}
直接分配 Future.value(Future.value(Student()))
时出现以下错误。
Error: The argument type 'Student' can't be assigned to the parameter type 'FutureOr<Future<User>>?'.
因为在函数中你定义了 return 类型并且 dart 知道 return 类型,但是当直接赋值时 dart 不知道 Future.value(Student())
有一个 Future<User>
类型].要解决此问题,您必须告诉飞镖值的类型,如下所示:Future.value((Future.value(Student())) as Future<User>);
这样 dart 就会知道这个值的类型并将其视为 Future<User>
.
这里的问题是 Future<T>.value
的参数具有类型 FutureOr<T>
。它可以是未来或价值。
此外,Dart 类型推断的工作原理是“下推”上下文类型,然后尝试使表达式在该类型上工作,最后将最终的静态类型向上推。
如果像 Future.value(...)
这样的表达式具有上下文类型,则始终从上下文类型推断缺少的类型参数。
写的时候
Future<Future<User>> fut2 = Future.value(Future.value(Student()));
外部Future.value
的上下文类型,我们知道它应该有的类型是Future<Future<User>>
。这使得它的参数具有上下文类型 FutureOr<Future<User>>
。
参数是 Future.value(Student())
,我们对 Student()
还一无所知,因为我们还没有在类型推断中得到它,我们仍在朝着它努力。
一个Future<X>
可以通过两种方式满足FutureOr<Future<User>>
,要么是Future<User>
,要么是Future<Future<User>>
。
类型推断然后猜测是后者。这是错误的,但它还看不到。类型推断的工作方式,当有上下文类型时它必须使用上下文类型,但上下文类型不明确,最终选择了错误的选项。
您遇到了类型推断的边缘情况,其中可以通过两种不同的方式满足上下文类型,而向下类型推断选择了错误的方式。这是一个很好的启发式方法,如果你有一个 FutureOr<...>
上下文类型,并且你看到一个 Future
构造函数,你需要 FutureOr<...>
的 Future
部分。当你有 FutureOr<Future<...>>
时它就会崩溃。所以,不要那样做!
总的来说,我的建议是 永远不要 在您的程序中包含 Future<Future<anything>>
。它不仅避免了此类问题,而且还是您代码的更好模型。
一个最终完成到最终完成到某个值的东西的未来……只是让它最终直接完成到那个值。等待中间的未来只是无谓的忙碌