首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >颤振Future<dynamic>与Future<String>亚型错误?

颤振Future<dynamic>与Future<String>亚型错误?
EN

Stack Overflow用户
提问于 2018-04-18 01:05:35
回答 1查看 13.9K关注 0票数 0

我刚刚更新了颤振,并成功地从git下载了我的原始项目。现在我得到了一个奇怪的Future错误。我看到在github网上提到过,但没有明确的答案来解决问题。这个项目甚至没有加载。它从我的main.dart文件中读取未来语句并返回这个..。

详细-2:dart_error.cc(16)未处理的异常:类型‘未来动态’不是‘未来字符串’类型的子类型 未来来自飞镖:异步 未来来自飞镖:异步 字符串来自dart:core

*不确定哪里有错误。我的省道分析说“等待未来”。这是我的未来代码,我运行之前,我的小部件开始建立..。

代码语言:javascript
运行
复制
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";
      }
    });
  }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-04-18 03:30:26

好的。我想我明白了。

Dart 1.0是一种软类型语言,所以类似于

代码语言:javascript
运行
复制
main() async {  
  print(await getData()); 
}

Future<Null> getDatare() async{return "a";} 

会打印"a“

问题是,Dart 2.0是一种类型化的语言,所以未来实际上是有意义的。这里发生的事情(简而言之)是,未来变成了一个FutureNull,而您不能从一个FutureNull获得一个字符串(因为它只包含一个空的)。

事实上,这种咬我的once1,但如果你想一想,这是有意义的。请查看以下代码:

代码语言:javascript
运行
复制
List<dynamic> l = ["a", "b", "c", "d"];
List<String> d = l;

甚至更糟

代码语言:javascript
运行
复制
List<int> l = [1,2,3,4];
List<double> d = l;

会在颤栗中坠毁。为什么?因为想想这里发生了什么:

什么是“我”?

代码语言:javascript
运行
复制
----------------------
| int | int | int | int |
----------------------

什么是"d"?

代码语言:javascript
运行
复制
---------------------------------------------
| double | double | double | double |
---------------------------------------------

那么你如何在"l“和"d”之间转换呢?

您必须创建一个新的双倍列表,然后复制l中的值,将其转换为double,然后将其存储在"d“中。

但这并不仅仅适用于清单。它适用于所有的仿制药。

当您有类似于A<B>的东西时,它是一个与A<C>完全不同的类型,并且您不能简单地从一个转换到另一个,而且出于同样的原因:

请使用以下代码:

代码语言:javascript
运行
复制
class Box<T> {
  T a;
  Box(T v) {
    a=v;
  }
  T getVal() {
    return a;
  }
  }

现在将Box转换为Box。没有道理,对吧?我能做以下几件事吗?

代码语言:javascript
运行
复制
Box<int> i = new Box(5);
Box<String> s= new Box("a");
i + (s as Box<int>)

所以这里真正发生的事情是,Box变成BoxInt,Box变成BoxString (编译器查找/替换标识符"T“以"int”或"T“替换为"String")。

所以这里有同样的事情:你必须打开未来的价值,然后处理它。在您的情况下(实际上,您的情况有一个额外的问题--您没有返回任何东西),您可能需要一个未来,然后await那个未来,并得到一个字符串。

1.它是怎么咬我的?来自Kotlin (或任何其他JVM语言),我习惯于这样做:

代码语言:javascript
运行
复制
List<A> a = ...;
List<B> b = a;

没有问题。为什么?因为JVM没有真正的泛型。它所做的被称为“类型擦除”,其中真正发生的是:

代码语言:javascript
运行
复制
List<Object> a = ...;
List<Object> b = a;

显然,这是可行的,因为所有List都持有一个指向对象的指针,该指针是在运行时确定的。

这是因为Java1.0(与Dart不同)从来没有泛型,而且它们是栓在一起的,因此为了向后兼容性,它们使得泛型的类型安全性不如它们能够做到的那样安全。

因此Dart (或C++、Rust或Go数组)将泛型视为单一形式,而Java将它们视为多态代码(将"T“作为指针)。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49889588

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档