forEach vs for in:调用方法时的不同行为 [英] forEach vs for in: Different Behavior When Calling a Method

查看:43
本文介绍了forEach vs for in:调用方法时的不同行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到 forEach for in 会产生不同的行为.我有一个 RegExp 列表,并且想在每个列表上运行 hasMatch .使用 forEach 遍历列表时, hasMatch 永远不会返回true.但是,如果我在中使用,则 hasMatch 返回true.

I noticed that forEach and for in to produce different behavior. I have a list of RegExp and want to run hasMatch on each one. When iterating through the list using forEach, hasMatch never returns true. However, if I use for in, hasMatch returns true.

示例代码:

class Foo {
  final str = "Hello";
  final regexes = [new RegExp(r"(\w+)")];

  String a() {
    regexes.forEach((RegExp reg) {
      if (reg.hasMatch(str)) {
        return 'match';
      }
    });
    return 'no match';
  }

  String b() {
    for (RegExp reg in regexes) {
      if (reg.hasMatch(str)) {
        return 'match';
      }
    }
    return 'no match';
  }
}

void main() {
  Foo foo = new Foo();
  print(foo.a()); // prints "no match"
  print(foo.b()); // prints "match"
}

(带有上述示例代码的DartPad )

方法 a b 之间的唯一区别是 a 使用 forEach b使用 for in ,但是它们会产生不同的结果.为什么会这样?

The only difference between the methods a and b is that a uses forEach and b uses for in, yet they produce different results. Why is this?

推荐答案

尽管有推荐反对使用 Iterable.forEach 和其他任何东西,并且有一个相应的

Although there is a prefer_foreach lint, that recommendation is specifically for cases where you can use it with a tear-off (a reference to an existing function). Effective Dart recommends against using Iterable.forEach with anything else, and there is a corresponding avoid_function_literals_in_foreach_calls lint to enforce it.

除了回调很简单的情况以外, Iterable.forEach 并不比使用基本且更通用的 for 循环简单.使用 Iterable.forEach 的陷阱更多,这就是其中之一.

Except for those simple cases where the callback is a tear-off, Iterable.forEach is not any simpler than using a basic and more general for loop. There are more pitfalls using Iterable.forEach, and this is one of them.

  • Iterable.forEach 是一个以 callback 作为参数的函数. Iterable.forEach 不是控件结构,并且回调是普通函数.因此,您不能使用 break 停止早期迭代,也不能使用 continue 跳至下一个迭代.

  • Iterable.forEach is a function that takes a callback as an argument. Iterable.forEach is not a control structure, and the callback is an ordinary function. You therefore cannot use break to stop iterating early or use continue to skip to the next iteration.

回调中的 return 语句从回调中返回,并且忽略返回值.Iterable.forEach 的调用者将永远不会收到返回的值,也永远不会有传播它的机会.例如,在:

A return statement in the callback returns from the callback, and the return value is ignored. The caller of Iterable.forEach will never receive the returned value and will never have an opportunity to propagate it. For example, in:

bool f(List<int> list) {
  for (var i in list) {
    if (i == 42) {
      return true;
    }
  }
  return false;
}

return true 语句从函数 f 返回并停止迭代.相反,使用 forEach :

the return true statement returns from the function f and stops iteration. In contrast, with forEach:

bool g(List<int> list) {
  list.forEach((i) {
    if (i == 42) {
      return true;
    }
  });
  return false;
}

return true 语句仅从回调返回.函数 g 直到完成所有所有迭代并在最后到达 return false 语句后才会返回.这也许更清楚:

the return true statement returns from only the callback. The function g will not return until it completes all iterations and reaches the return false statement at the end. This perhaps is clearer as:

bool callback(int i) {
  if (i == 42) {
    return true;
  }
}

bool g(List<int> list) {
  list.forEach(callback);
  return false;
}

这使得显而易见的是:

  1. 回调无法使 g 返回 true .
  2. 回调不会沿所有路径返回值.
  1. There is no way for callback to cause g to return true.
  2. callback does not return a value along all paths.

(那是您遇到的问题.)

(That's the problem you encountered.)

Iterable.forEach 不得与异步回调一起使用.因为回调函数返回的任何值都将被忽略,所以异步回调函数永远都不会等待.

Iterable.forEach must not be used with asynchronous callbacks. Because any value returned by the callback is ignored, asynchronous callbacks can never be waited upon.

我还应该指出,如果您启用Dart的新的null安全功能(该功能可以进行更严格的类型检查),您的 forEach 代码将生成错误,因为它会在以下回调中返回一个值:预期具有 void 返回值.

I should also point out that if you enable Dart's new null-safety features, which enable stricter type-checking, your forEach code will generate an error because it returns a value in a callback that is expected to have a void return value.

这篇关于forEach vs for in:调用方法时的不同行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆