Flutter Future <dynamic> vs. Future <string>子类型错误?

时间:2018-04-18 01:05:35

标签: asynchronous dynamic dart future flutter

我刚刚更新了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";
      }
    });
  }

1 个答案:

答案 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;作为指针)。