prefer-last
Same as prefer-last in Dart Code Metrics
- Group
- Style
- Path
lint/style/prefer-last- Default
- Off, opt in
- Origin
- Dart Code Metrics
- Rule
- 383 of 512
Flags manual last-element indexing in favor of the .last getter.
Catches the xs[xs.length - 1] idiom, where the receiver and the collection
whose length is read are the same identifier. Iterables expose a dedicated
.last getter that reads more clearly, avoids repeating the receiver, and
removes the off-by-one arithmetic that manual indexing invites. The match is
deliberately narrow: it requires a literal - 1 subtracted from <name>.length
indexing <name>, so unrelated index expressions are left alone.
Invalid
// Bad: using [list.length - 1] instead of .last
void example() {
final items = [1, 2, 3];
final last = items[items.length - 1];
print(last);
}
class Processor {
String getLastName(List<String> names) {
return names[names.length - 1];
}
void processTail(List<int> values) {
final tail = values[values.length - 1];
if (tail > 0) {
compute(tail);
}
}
}
void multipleViolations(List<String> items) {
final a = items[items.length - 1];
final b = items[items.length - 1].length;
print('$a $b');
}
// Regression: the violation must be found inside Dart 3 containers too.
void containers(List<int> xs, int count) {
final (a, _) = (xs[xs.length - 1], 0);
int b;
int _u;
(b, _u) = (xs[xs.length - 1], 0);
lbl: {
final c = xs[xs.length - 1];
print(c);
}
final d = switch (count) {
0 => xs[xs.length - 1],
_ => 0,
};
final e = switch (xs[xs.length - 1]) {
_ => 0,
};
final f = [if (count > 0) xs[xs.length - 1]];
final g = [...[xs[xs.length - 1]]];
final h = (p: xs[xs.length - 1], q: 0);
assert(xs[xs.length - 1] > 0, "x");
print([a, b, d, e, f, g, h]);
} final items = [1, 2, 3]; final last = items[items.length - 1]; String getLastName(List<String> names) { return names[names.length - 1]; void processTail(List<int> values) { final tail = values[values.length - 1];void multipleViolations(List<String> items) { final a = items[items.length - 1]; final a = items[items.length - 1]; final b = items[items.length - 1].length;void containers(List<int> xs, int count) { final (a, _) = (xs[xs.length - 1], 0); int _u; (b, _u) = (xs[xs.length - 1], 0); lbl: { final c = xs[xs.length - 1]; final d = switch (count) { 0 => xs[xs.length - 1], }; final e = switch (xs[xs.length - 1]) { }; final f = [if (count > 0) xs[xs.length - 1]]; final f = [if (count > 0) xs[xs.length - 1]]; final g = [...[xs[xs.length - 1]]]; final g = [...[xs[xs.length - 1]]]; final h = (p: xs[xs.length - 1], q: 0); final h = (p: xs[xs.length - 1], q: 0); assert(xs[xs.length - 1] > 0, "x");Valid
// Good: using .last
void example() {
final items = [1, 2, 3];
final last = items.last;
print(last);
}
class Processor {
String getLastName(List<String> names) {
return names.last;
}
void processTail(List<int> values) {
final tail = values.last;
if (tail > 0) {
compute(tail);
}
}
}
void multipleAccess(List<String> items) {
final a = items.last;
final b = items.last.length;
print('$a $b');
}
// OK: accessing non-last indices
void accessOther(List<int> items) {
final secondToLast = items[items.length - 2];
final third = items[2];
}
// OK: in loop context
void loopAccess(List<List<int>> matrix) {
for (int i = 0; i < matrix.length; i++) {
final row = matrix[i]; // accessing by variable index is OK
}
}Configure prefer-last
Set its severity in falcon.json. See the configuration guide.
{
"linter": {
"rules": {
"style": {
"prefer-last": "error"
}
}
}
}Or silence one occurrence with a suppression comment; the reason is required.
// falcon-ignore lint/style/prefer-last: <reason>More style rules
- prefer-match-file-name
Match a file's sole class or enum name to its snake-case basename.
- prefer-mixin
prefer_mixinrecommendedFlags
withclauses that mix in a plain class instead of a mixin. - prefer-multi-bloc-providerbloc
Flatten directly nested
package:flutter_blocBlocProviderswithMultiBlocProvider. - prefer-multi-providerprovider
Prefer a flat
MultiProviderto directly nested provider widgets. - prefer-named-boolean-parameters
Flags explicit positional
boolparameters in private declarations and unconstrained closures. - prefer-named-parameters
Prefer named parameters when a declaration exceeds
max-number(default 1). - prefer-null-aware-method-calls
prefer_null_aware_method_callsrecommendedPrefers
f?.call()to calling a null-checked function after a!= nulltest. - prefer-padding-over-containerflutter
Prefers
Paddingover aContainerused only forpadding.