我刚刚更新了Flutter并成功从git
下载了原始项目。现在我收到了一个奇怪的Future
错误。我在github上看到了它的在线提及,但没有关于如何修复的明确答案。该项目甚至没有加载。它从我的main.dart文件中读取Future语句并返回此...
[VERBOSE-2:dart_error.cc(16)]未处理的异常:类型 “未来动态”不是“未来字符串”类型的子类型 未来来自dart:async
未来来自dart:async
字符串是 来自dart:core
***不确定错误在哪里。我的飞镖分析说“等待期货”。这是我在我的小部件开始构建之前运行的期货代码......
Future<Null> getData() async{
FirebaseUser user = await FirebaseAuth.instance.currentUser;
user = FirebaseAuth.instance.currentUser;
var userid = user.uid;
fb.child('users/${userid}').onValue.listen((Event event) {
if (event.snapshot.value != null) {
name = event.snapshot.value['displayName'];
image = event.snapshot.value['image'];
} else {
name = "User";
}
});
}
答案 0 :(得分:5)
确定。我想我明白了。
Dart 1.0,是一种软输入语言,所以像
main() async {
print(await getData());
}
Future<Null> getDatare() async{return "a";}
将打印&#34; a&#34;
事实是,Dart 2.0是一种打字语言,所以Future实际上有意义。这里发生的事情(简而言之)就是Future变成了FutureNull,你无法从FutureNull中获取一个String(因为它只包含一个Null)。
实际上,这种情况曾经让我感到痛苦[1],但如果你想一想,那就有道理了。请查看以下代码:
List<dynamic> l = ["a", "b", "c", "d"];
List<String> d = l;
甚至更多
List<int> l = [1,2,3,4];
List<double> d = l;
Flutter会崩溃。为什么?因为想想这里发生的事情:
什么是&#34; l&#34;?
----------------------
| int | int | int | int |
----------------------
什么是&#34; d&#34;?
---------------------------------------------
| double | double | double | double |
---------------------------------------------
那你怎么转换&#34; l&#34;和&#34; d&#34;?
您必须创建一个新的双打列表,然后将l中的值,将其复制到一个double中,然后将其存储在&#34; d&#34中;
但这并不适用于列表。它适用于所有泛型。
如果您拥有A<B>
之类的内容,那么与<{1}}完全不同类型,并且您无法将其从一个投射到其他,并出于同样的原因:
请使用以下代码:
A<C>
现在将Box转换为Box。没有意义,对吧?我可以这样做吗?
class Box<T> {
T a;
Box(T v) {
a=v;
}
T getVal() {
return a;
}
}
所以这里真正发生的是Box变为BoxInt,Box变为BoxString(编译器找到/替换标识符&#34; T&#34;&#34; int&#34;或&#34; T& #34;使用&#34;字符串&#34;)。
所以你在这里有同样的事情:你必须从未来取消装箱,然后再使用它。在你的情况下(实际上,你的案例还有一个问题 - 你没有返回任何东西)你可能想要一个Future,然后Box<int> i = new Box(5);
Box<String> s= new Box("a");
i + (s as Box<int>)
那个Future并获得一个String。
[1]。它是怎么咬我的?来自Kotlin(或任何其他JVM语言),我习惯于能够做类似的事情:
await
没有问题。为什么?因为JVM没有真正的泛型。它的作用被称为&#34;类型擦除&#34;,其中发生了什么:
List<A> a = ...;
List<B> b = a;
嗯,这显然有效,因为所有List<Object> a = ...;
List<Object> b = a;
都持有一个指向对象的指针,在运行时确定。
那是因为Java 1.0(不像Dart)从来没有使用过泛型,而且它们都是用螺栓固定的,所以为了向后兼容,它们使得泛型的安全性低于它们可能的类型。
所以Dart(或C ++或Rust或Go数组)将泛型视为单态,而Java将它们视为多态代码(对待&#34; T&#34;作为指针)。