Cha*_* Jr 0 asynchronous future dynamic dart flutter
我刚刚更新了Flutter,并成功从中下载了我的原始项目git。现在我收到一个奇怪的Future错误。我可以在github上在线看到它,但是没有关于如何修复的明确答案。该项目甚至没有加载。它从我的main.dart文件中读取Future语句并返回此...
[VERBOSE-2:dart_error.cc(16)]未处理的异常:类型'Future dynamic'不是类型'Future String'的子类型,其中
Future来自dart:async
Future来自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";
}
});
}
Run Code Online (Sandbox Code Playgroud)
好。我想我明白了。
Dart 1.0是一种软类型语言,所以类似
main() async {
print(await getData());
}
Future<Null> getDatare() async{return "a";}
Run Code Online (Sandbox Code Playgroud)
会打印“ a”
事实是Dart 2.0是一种类型化的语言,因此Future实际上具有含义。简而言之,这里发生的是Future成为FutureNull,并且您无法从FutureNull获取字符串(因为它仅包含Null)。
其实,这曾经让我有点难过[1],但是如果您考虑一下,那是有道理的。看下面的代码:
List<dynamic> l = ["a", "b", "c", "d"];
List<String> d = l;
Run Code Online (Sandbox Code Playgroud)
甚至更多
List<int> l = [1,2,3,4];
List<double> d = l;
Run Code Online (Sandbox Code Playgroud)
将在Flutter中崩溃。为什么?因为想想这里发生了什么:
什么是“ l”?
----------------------
| int | int | int | int |
----------------------
Run Code Online (Sandbox Code Playgroud)
什么是“ d”?
---------------------------------------------
| double | double | double | double |
---------------------------------------------
Run Code Online (Sandbox Code Playgroud)
那么,如何在“ l”和“ d”之间转换?
您必须创建一个新的双精度列表,然后将值复制到l中,将其转换为双精度,然后将其存储在“ d”中。
但这不仅适用于列表。它适用于所有泛型。
当你碰到这样的A<B>,这是一个完全不同的类型比A<C>,你可以不投简单地从一个转换为另一个,并出于同样的原因:
采取以下代码:
class Box<T> {
T a;
Box(T v) {
a=v;
}
T getVal() {
return a;
}
}
Run Code Online (Sandbox Code Playgroud)
现在将Box转换为Box。没道理吧?我可以做以下事情吗?
Box<int> i = new Box(5);
Box<String> s= new Box("a");
i + (s as Box<int>)
Run Code Online (Sandbox Code Playgroud)
因此,这里真正发生的是Box变成BoxInt,而Box变成BoxString(通过编译器查找/将标识符“ T”替换为“ int”或将“ T”替换为“ String”)。
因此,您在这里遇到了同样的事情:您必须从未来拆箱价值,然后再使用它。在您的情况下(实际上,您的情况还有另一个问题-您什么也不返回),您可能想要一个Future,然后await该Future并获取一个String。
[1]。它是怎么咬我的?来自Kotlin(或任何其他JVM语言),我习惯于执行以下操作:
List<A> a = ...;
List<B> b = a;
Run Code Online (Sandbox Code Playgroud)
没问题。为什么?因为JVM没有真正的泛型。它所做的被称为“类型擦除”,实际上发生了什么:
List<Object> a = ...;
List<Object> b = a;
Run Code Online (Sandbox Code Playgroud)
好吧,这显然是可行的,因为所有人都List拥有一个指向对象的指针,该指针是在运行时确定的。
那是因为Java 1.0(与Dart不同)从未使用过泛型,并且使用了泛型,因此为了向后兼容,它们使泛型的类型安全性降低了。
因此Dart(或C ++或Rust或Go数组)将泛型视为单态,而Java将它们视为多态代码(将“ T”作为指针)。
| 归档时间: |
|
| 查看次数: |
7505 次 |
| 最近记录: |