记录一个dart里的低级但常犯的语法错误 ( forEach vs any )

16 篇文章 1 订阅
5 篇文章 1 订阅

下面这是一段我们常写出的代码,注意其中的forEach函数,大家看看它的输出是什么。

void main(List<String> arguments) {
  print(Test.inList('1'));
  Test.list.add('1');
  print(Test.inList('1'));
}

class Test {
  static var list = <String>[];

  static bool inList(String template) {
    list.forEach((String item) {
      if (template == item) {
        return true;
      } else {
        return false;
      }
    });

    return false;
  }
}

我们会想当然的认为第一次print是false,第二次print是true。
然而实际上的输出

false
false

这里是forEach这个函数有个坑

  /**
   * Applies the function [f] to each element of this collection in iteration
   * order.
   */
  void forEach(void f(E element)) {
    for (E element in this) f(element);
  }

这是forEach的实现,非常的简单。注意这里传入的函数参数 f 的返回值是void。
函数的实现里也没有对f的返回值做任何处理,毕竟人家声明的就是void——无返回值。

虽然我们在使用的时候,f的实现里面写了return true|false ,并且编译器并没有报错,但是实际上,这里的return是毫无意义的。

更不可能会把当前函数inList的运行中断掉并返回。

那么知道了这个问题,该怎么解决呢?

可以简单的使用any函数。

  /**
   * Checks whether any element of this iterable satisfies [test].
   *
   * Checks every element in iteration order, and returns `true` if
   * any of them make [test] return `true`, otherwise returns false.
   */
  bool any(bool test(E element)) {
    for (E element in this) {
      if (test(element)) return true;
    }
    return false;
  }

any函数和forEach的使用类似, 但是处理了传入函数test的返回值。

  static bool inList(String template) {
   return list.any((String item) {
     if (template == item) {
       return true;
     } else {
       return false;
     }
   });
 }

改成这样既可,注意及时是any函数,也是不能让return直接中断inList的执行并返回的,return的值是传递到any函数的返回上,然后return any函数的返回既可。

上述代码略显啰嗦,可以再优化下,用一行代码实现:

static bool inList(String template) => list.any((String item) => template == item);

再次运行,就输出了期望的结果

false
true
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,以下是一个简单的 Dart 线程池工具类的示例代码: ```dart import 'dart:collection'; import 'dart:async'; class ThreadPool { int _maxThreads; Queue<Function> _workQueue = Queue<Function>(); List<Worker> _workers = []; ThreadPool(this._maxThreads) { for (int i = 0; i < _maxThreads; i++) { _workers.add(Worker(_workQueue)); } } Future execute(Function task) async { Completer completer = Completer(); _workQueue.add(() async { await task(); completer.complete(); }); return completer.future; } void shutdown() { _workers.forEach((worker) => worker.stop()); } } class Worker { final Queue<Function> _workQueue; bool _isRunning = true; Worker(this._workQueue) { _start(); } void _start() async { while (_isRunning) { if (_workQueue.isNotEmpty) { var task = _workQueue.removeFirst(); await task(); } else { await Future.delayed(Duration(milliseconds: 100)); } } } void stop() { _isRunning = false; } } ``` 使用示例: ```dart void main() async { var threadPool = ThreadPool(2); await threadPool.execute(() async { print('Task 1 started'); await Future.delayed(Duration(seconds: 2)); print('Task 1 completed'); }); await threadPool.execute(() async { print('Task 2 started'); await Future.delayed(Duration(seconds: 1)); print('Task 2 completed'); }); await threadPool.execute(() async { print('Task 3 started'); await Future.delayed(Duration(seconds: 3)); print('Task 3 completed'); }); threadPool.shutdown(); } ``` 这个示例代码中,我们首先定义了一个 `ThreadPool` 类,它包含了一个任务队列 `_workQueue` 和一个线程池 `_workers`。在构造函数中,我们初始化了 `_workers` 数组并创建了若干个 `Worker` 实例,每个 `Worker` 实例都会从 `_workQueue` 中取出任务并执行。 `execute` 方法用于添加任务到队列中,它会返回一个 `Future` 对象,用于等待任务执行完成。 `Worker` 类是一个内部类,用于表示线程池中的一个工作者。它会持续地从任务队列中取出任务并执行,直到线程池被关闭。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值