forEach called with a one-parameter function literal
ID |
dart.performance.avoid_function_literals_foreach |
Severity |
info |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Idiom |
Language |
Dart |
Description
Reports forEach called with a single-parameter function literal, in arrow or block form, where a for-in loop expresses the same iteration. Passing an existing function as a tear-off (items.forEach(print)) is not reported, and neither is an awaited Stream.forEach, which has no for-in equivalent.
Rationale
The closure turns every element into a call: the loop body cannot be inlined into the caller, and it captures the enclosing scope, so a forEach in a hot path pays for a closure allocation plus one indirect call per element that a for-in loop does not. The closure also changes what the body is allowed to do - break, continue and return no longer refer to the iteration, so an early exit has to be faked with a flag or an exception, and an await inside the literal does not suspend the iteration, which is a silent source of interleaved work. A for-in loop has none of these restrictions.
The following code illustrates the pattern detected by this rule:
class Audit {
final List<String> events;
Audit(this.events);
void logAll() {
// FLAGGED: forEach called with a one-parameter function literal
events.forEach((e) {
print(e);
});
}
}