在dart中引入该程序的后果如何?
为什么下面的代码有效?我认为应该有编译时错误。我认为主体中的返回值返回intvalue 1。如果不是,则它必须返回一个Future,该Future也不符合返回类型。等待发生了什么 void longRun异步{ 返回等待未来 持续时间秒:3, =>1, ; } 如果我将wait部分赋值给一个变量,如下面所示,编译器就会开始抱怨,这很明显,也很容易理解。但是为什么上面的代码没有抱怨呢 void longRun异步{ var foo=wait Future.delayed 持续时间秒:3, =>1, ; 返回foo; } 继续研究,我发现了更令人困惑的事情:以下所有版本都可以工作。他们看起来一模一样,有联系 版本1:在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,
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也很有帮助。兔子洞这么深,谢谢!!我会把这个书签起来以备日后参考。您包含的链接也非常有用。