Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在dart中引入该程序的后果如何?_Dart_Async Await_Future - Fatal编程技术网

在dart中引入该程序的后果如何?

在dart中引入该程序的后果如何?,dart,async-await,future,Dart,Async Await,Future,为什么下面的代码有效?我认为应该有编译时错误。我认为主体中的返回值返回intvalue 1。如果不是,则它必须返回一个Future,该Future也不符合返回类型。等待发生了什么 void longRun异步{ 返回等待未来 持续时间秒:3, =>1, ; } 如果我将wait部分赋值给一个变量,如下面所示,编译器就会开始抱怨,这很明显,也很容易理解。但是为什么上面的代码没有抱怨呢 void longRun异步{ var foo=wait Future.delayed 持续时间秒:3, =>1,

为什么下面的代码有效?我认为应该有编译时错误。我认为主体中的返回值返回intvalue 1。如果不是,则它必须返回一个Future,该Future也不符合返回类型。等待发生了什么

void longRun异步{ 返回等待未来 持续时间秒:3, =>1, ; } 如果我将wait部分赋值给一个变量,如下面所示,编译器就会开始抱怨,这很明显,也很容易理解。但是为什么上面的代码没有抱怨呢

void longRun异步{ var foo=wait Future.delayed 持续时间秒:3, =>1, ; 返回foo; } 继续研究,我发现了更令人困惑的事情:以下所有版本都可以工作。他们看起来一模一样,有联系

版本1:

void longRun() async {
   return await Future.delayed(Duration(seconds:2), ()=>1);
}
版本2:

Future<void> longRun() async {
   return await Future.delayed(Duration(seconds:2), ()=>1);
}
版本5:

Future longRun() async {
   await Future.delayed(Duration(seconds:2), ()=>1);
}
版本6:

void longRun() async {
   await Future.delayed(Duration(seconds:2), ()=>1);
}

这主要是关于=>的行为,而不是等待。通常=>1可以被认为是{return 1;}的简写,但这实际上过于简单化了

=>允许使用void函数,以方便用户编写以下内容:

具有侧向效应的布尔函数{ 打印“一些副作用”; 返回true; } void foo=>functionWithSideEffect; int _someValue=0; 设置someValueint value=>\u someValue=value; 尽管这些都不合法:

瓦福{ //错误:无法从函数“foo”返回类型为“bool”的值 //因为它的返回类型为“void”。 具有ideeffect的返回函数; } 设置someValueint值{ //错误:无法从函数返回“int”类型的值 //“someValue”,因为它的返回类型为“void”。 返回_someValue=value; } 混淆的关键在于=>1可以是int函数,也可以是void函数,并且类型推断会根据不同的约束选择不同的内容

当您这样做时:

void longRun异步{ 返回等待未来 持续时间秒:3, =>1, ; } 然后类型推断从外到内工作,通过无约束的返回表达式传播longRun的void返回类型。Future.delayed调用被推断为Future.delayed,而=>1回调被推断为void函数。可以说,返回Future的void异步函数可以被视为错误

相反,当您这样做时:

void longRun异步{ var foo=wait Future.delayed 持续时间秒:3, =>1, ; 返回foo; } 现在,类型推断从内到外朝着另一个方向运行:foo没有显式类型,因此它不约束右侧。因此=>1被假定为int函数,这导致Future.delayed被推断为Future.delayed,而foo被推断为int。由于foo是int,尝试从声明为返回void的函数返回它是一个错误

版本2:

Future<void> longRun() async {
   return await Future.delayed(Duration(seconds:2), ()=>1);
}
未来长运行异步{ 返回等待未来。延迟持续时间秒:2,=>1; } 您已将longRun的返回类型从void更改为Future。与版本1的唯一区别在于,调用方现在可以在longRun完成时等待并触发回调。=>1仍然被推断为空函数

版本3:

Future<int> longRun() async {
   return await Future.delayed(Duration(seconds:2), ()=>1);
}
未来长运行异步{ 返回等待未来。延迟持续时间秒:2,=>1; } 除了longRun返回Future而不是Future之外,与version2相同。现在=>1被推断为int函数

版本4:

Future longRun() async {
   return await Future.delayed(Duration(seconds:2), ()=>1);
}
未来长运行异步{ 返回等待未来。延迟持续时间秒:2,=>1; } longRun的返回类型是now Future,这意味着Future.=>1被推断为动态函数

版本5:

Future longRun() async {
   await Future.delayed(Duration(seconds:2), ()=>1);
}
未来长运行异步{ 等待未来。延迟持续时间秒:2,=>1; } 与version4相同,只是没有显式返回语句。现在Future.delayed表达式不再受longRun返回类型的约束,推理将由内而外流动;=>1被假定为int函数

版本6:

void longRun() async {
   await Future.delayed(Duration(seconds:2), ()=>1);
}
void longRun异步{ 等待未来。延迟持续时间秒:2,=>1; } 与version5相同,只是longRun返回void,是一个fire-and-forget函数。longRun完成时无法通知调用方

注意,在上面,当我write=>1被推断为int函数或void函数时,它实际上应该是FutureOr函数或FutureOr函数,但这不是重要的部分

编辑:

预先解决一些潜在的后续问题:

原因是:

void longRun异步{ int f{ 返回1; } 返回等待未来 持续时间秒:3, F ; } 好的,但是:

void longRun异步{ 返回等待未来 持续时间秒:3, //信息:不指定为空。 { 返回1; }, ; } 是否生成分析投诉?这两个版本都是合法的,因为当U是T的子类型时,用未来代替未来是合法的。当T无效时,U可以是任何东西;该值可以忽略。在Dart中,部分是由于历史原因,它并不总是有空洞类型,空洞实际上意味着 s表示该值不能使用,而不是没有值。空隙x=42;是合法的,但尝试读取x的值将是错误的。这就是为什么“不分配给无效分析”投诉未被归类为错误的原因


在使用匿名函数的第二个版本中,return语句的更紧密的局部性允许分析器执行更广泛的检查。

这主要是关于=>的行为,而不是等待。通常=>1可以被认为是{return 1;}的简写,但这实际上过于简单化了

=>允许使用void函数,以方便用户编写以下内容:

具有侧向效应的布尔函数{ 打印“一些副作用”; 返回true; } void foo=>functionWithSideEffect; int _someValue=0; 设置someValueint value=>\u someValue=value; 尽管这些都不合法:

瓦福{ //错误:无法从函数“foo”返回类型为“bool”的值 //因为它的返回类型为“void”。 具有ideeffect的返回函数; } 设置someValueint值{ //错误:无法从函数返回“int”类型的值 //“someValue”,因为它的返回类型为“void”。 返回_someValue=value; } 混淆的关键在于=>1可以是int函数,也可以是void函数,并且类型推断会根据不同的约束选择不同的内容

当您这样做时:

void longRun异步{ 返回等待未来 持续时间秒:3, =>1, ; } 然后类型推断从外到内工作,通过无约束的返回表达式传播longRun的void返回类型。Future.delayed调用被推断为Future.delayed,而=>1回调被推断为void函数。可以说,返回Future的void异步函数可以被视为错误

相反,当您这样做时:

void longRun异步{ var foo=wait Future.delayed 持续时间秒:3, =>1, ; 返回foo; } 现在,类型推断从内到外朝着另一个方向运行:foo没有显式类型,因此它不约束右侧。因此=>1被假定为int函数,这导致Future.delayed被推断为Future.delayed,而foo被推断为int。由于foo是int,尝试从声明为返回void的函数返回它是一个错误

版本2:

Future<void> longRun() async {
   return await Future.delayed(Duration(seconds:2), ()=>1);
}
未来长运行异步{ 返回等待未来。延迟持续时间秒:2,=>1; } 您已将longRun的返回类型从void更改为Future。与版本1的唯一区别在于,调用方现在可以在longRun完成时等待并触发回调。=>1仍然被推断为空函数

版本3:

Future<int> longRun() async {
   return await Future.delayed(Duration(seconds:2), ()=>1);
}
未来长运行异步{ 返回等待未来。延迟持续时间秒:2,=>1; } 除了longRun返回Future而不是Future之外,与version2相同。现在=>1被推断为int函数

版本4:

Future longRun() async {
   return await Future.delayed(Duration(seconds:2), ()=>1);
}
未来长运行异步{ 返回等待未来。延迟持续时间秒:2,=>1; } longRun的返回类型是now Future,这意味着Future.=>1被推断为动态函数

版本5:

Future longRun() async {
   await Future.delayed(Duration(seconds:2), ()=>1);
}
未来长运行异步{ 等待未来。延迟持续时间秒:2,=>1; } 与version4相同,只是没有显式返回语句。现在Future.delayed表达式不再受longRun返回类型的约束,推理将由内而外流动;=>1被假定为int函数

版本6:

void longRun() async {
   await Future.delayed(Duration(seconds:2), ()=>1);
}
void longRun异步{ 等待未来。延迟持续时间秒:2,=>1; } 与version5相同,只是longRun返回void,是一个fire-and-forget函数。longRun完成时无法通知调用方

注意,在上面,当我write=>1被推断为int函数或void函数时,它实际上应该是FutureOr函数或FutureOr函数,但这不是重要的部分

编辑:

预先解决一些潜在的后续问题:

原因是:

void longRun异步{ int f{ 返回1; } 返回等待未来 持续时间秒:3, F ; } 好的,但是:

void longRun异步{ 返回等待未来 持续时间秒:3, //信息:不指定为空。 { 返回1; }, ; } 是否生成分析投诉?这两个版本都是合法的,因为当U是T的子类型时,用未来代替未来是合法的。当T无效时,U可以是任何东西;该值可以忽略。在Dart中,部分是由于历史原因,当它不总是具有void类型时,void实际上意味着不能使用该值,而不是没有值。空隙x=42;是合法的,但尝试读取x的值将是错误的。这就是为什么“不分配给无效分析”投诉未被归类为错误的原因


在使用匿名函数的第二个版本中,return语句的更紧密的局部性允许分析器执行更广泛的检查。

太深了,谢谢!!我会把这个书签起来以备日后参考。你包含的链接
ded也很有帮助。兔子洞这么深,谢谢!!我会把这个书签起来以备日后参考。您包含的链接也非常有用。