在下面的代码中(Dart 2.4.0 Windows),从指示返回类型 String 的 future 返回 null 会导致:
I/flutter ( 8735): The following assertion was thrown building Builder:
I/flutter ( 8735): type 'Future<dynamic>' is not a subtype of type 'Future<String>'
如果我返回“null as String;”,VSCode 会显示警告“unnecessary cast”,但是,代码可以运行,我不会收到 fatal error 。 有问题的代码如下。我已经注释掉导致问题的行,现在返回“null as String”。 我一直在 Dart 中使用 null String 没有问题,所以它似乎只是 Futures AFAIK 的问题。 这只是关于 Dart 和 Futures 的一个已知事实吗?这就是解决方法(“将 null 作为字符串返回”)?
@override
void initState() {
super.initState();
Future<String> future = _initPreferences();
future.then((sError) {
if (sError != null) debugPrint("\n*** Error from initPrefs = $sError\n");
if (sError == null) debugPrint("\n***Preferences were initialized OK\n");
});
}
Future<String> _initPreferences() {
return SharedPreferences.getInstance().then((prefs) {
_prefs = prefs;
//return null;
return null as String;
}).catchError((vError) {
return "Unable to load categories";
});
}
最佳答案
您在使用 Future.then
时没有指定类型,所以必须推断。自从你回来null
,它不知道它应该是什么类型,所以你调用 Future.then
不返回 Future<String>
.
您可以通过 then<String>(...)
显式指定类型来帮助推理引擎。 :
Future<String> _initPreferences() {
return SharedPreferences.getInstance().then<String>((prefs) {
_prefs = prefs;
return null;
}).catchError((vError) {
return "Unable to load categories";
});
}
尽管使用 async
会更好和 await
:
Future<String> _initPreferences() async {
try {
final prefs = await SharedPreferences.getInstance();
_prefs = prefs;
return null;
} catch (vError) {
return "Unable to load categories";
}
}
这里是一个更简单的复现案例:
Future<String> foo() {
final future = Future(() => null);
print('${future.runtimeType}');
return future;
}
Future<void> main() async {
await foo();
}
我希望 future
成为Future<Null>
, 但它最终是一个 Future<dynamic>
相反,我不确定为什么。 ( Null
是特殊的,允许将 Future<Null>
分配给 Future<T>
。)我怀疑这可能是一个错误,因为 dartanalyzer
不会生成任何关于它的警告。 (与一些评论所说的相反,这似乎不是 Dart 2.4.0 的新功能;我尝试使用 Dart 2.3.0、2.3.2 和 2.4.0。)我已经提交了 an issue about it .
关于Flutter、Dart 和 Future。这是 Dart Futures 的已知功能并且为空吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56796121/