这些函数返回值在 Dart 中是如何工作的?

Posted

技术标签:

【中文标题】这些函数返回值在 Dart 中是如何工作的?【英文标题】:How do these function return values work in Dart? 【发布时间】:2020-01-05 22:53:11 【问题描述】:

official Bloc documentation 给出了这个代码 sn-p:

Stream<int> countStream(int max) async* 
    for (int i = 0; i < max; i++) 
        yield i;
    

这个看起来对我来说非常简单,直到我意识到这个函数没有返回任何东西(没有returnstatement),但一直产生(对我来说 - 来自 python - 与return语句相同)。

还有这个例子,更清楚:

Future<int> sumStream(Stream<int> stream) async 
    int sum = 0;
    await for (int value in stream) 
        sum += value;
    
    return sum;

这里有一个明确返回的int但是如果我没看错的话,函数定义应该返回一个Future&lt;int&gt;type:

Future<int> sumStream(Stream<int> stream) async  //...

现在,这是如何工作的?我在这里有点困惑。

提前致谢! 阿克塞尔。

【问题讨论】:

【参考方案1】:

对于您的第一个示例,countStream 是一个使用 async* 设计的整数Stream。 (照顾好星星) 在这个流定义中,在流流上产生 emit 一个新整数(如 stream 所说的整数。 如果你消费流,你会得到 0,1,2,3,4,...,max-1

在第二个 sn-p 中,将其读作: sumStream is 一个 Future 必须返回一个 int。 更一般地说,一个 Future 实例产生一个 T 类型的值。 sumStream 将消耗一个流(在参数中给出),只要这个流有值,就对它们求和并在完成时返回最后一个总和。 Sum 是一个整数:Future 定义可以。

同时使用,你可以拥有:

> void main() async     
   print(await sumStream(countStream(5)));   

结果:1​​0 (0+1+2+3+4)

由于 sumStream 是一个 Future,main 可以等待异步执行:它声明它使用异步函数的意图(异步声明),然后它可以使用 await 停止自己的执行,直到 sumStream 返回。

如果你在没有异步的情况下离开 main 的另一种方法是在 Future 中添加 .then 子句:

void main()  
  sumStream(countStream(5)).then((x)=>print(x));
  print("after sumStream");

结果: 在 sumStream 之后 10

您可以看到 sumStream 的主要传递已经开始但尚未完成并首先打印(“sumStream 之后”)。 然后 main 完成了,但是 Dart 知道还有异步作业在运行,它会一直等到一切都完成,所以我们可以看到结果,但是一旦 Future sumStream 完成。

HTH

【讨论】:

【参考方案2】:

这对我来说看起来很简单,直到我意识到这个函数没有返回任何东西(没有返回语句)

首先,这个函数返回Stream&lt;int&gt;函数声明中指定的结果值。该函数通常称为生成器函数。

Stream<int> countStream(int max) async*

函数体代码(生成器)将生成int 值,并将这些生成的值生成给最初返回的Stream&lt;int&gt; 流。

语句yield在这种情况下意味着以下工作逻辑: 向Stream&lt;int&gt; 控制器添加一个值,然后返回到该语句yield 之后的函数主体中的下一条语句。

类似这样的:

import 'dart:async';

Future<void> main() async 
  await for (final i in countStream(5)) 
    print(i);
  


Stream<int> countStream(int max) 
  int i;
  final _ctl$ = StreamController<int>();
  void Function(int) _switchState$;
  _switchState$ = (int _state$) 
    while (true) 
      switch (_state$) 
        case 0:
          // for (int i = 0;
          i = 0;
          _state$ = 1;
          break;
        case 1:
          // i < max;
          if (i < max) 
            _state$ = 2;
           else 
            return;
          
          break;
        case 2:
          // yield i;
          _ctl$.add(i);
          Timer.run(() => _switchState$(3));
          return;
        case 3:
          // i++
          i++;
          _state$ = 1;
          break;
      
    
  ;

  Timer.run(() => _switchState$(0));
  return _ctl$.stream;

结果:

0 1 2 3 4

【讨论】:

以上是关于这些函数返回值在 Dart 中是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章

如何查看DLL中的函数信息

form_Valid 函数在 django 中是如何工作的?

Dart,如何在你自己的函数中创建一个返回的未来?

返回语句在 JavaScript 中是如何工作的? [复制]

C ++用户定义函数返回不正确[关闭]

如何在 Dart 中扩展函数?