prefer-final-locals
Same as prefer_final_locals in Dart lints
- Group
- Style
- Path
lint/style/prefer-final-locals- Default
- On (recommended)
- Origin
- Dart lints
- Rule
- 356 of 512
Prefer final for local variable declarations that are never reassigned.
A local declared with var (or just a type) that is initialized and never
written again reads better as final: the reader learns at the declaration
that the value does not change. Writes are tracked lexically across the
whole enclosing body, including closures, so a variable assigned anywhere
in its scope is left alone. Pattern declarations (var (a, b) = r;),
variables bound by for (var (a, b) in pairs), and variable patterns in
if-case clauses, switch statement cases, and switch expression arms
are covered too. Like the analyzer, patterns outside any function body (in
top-level variable and field initializers) are not reported.
Local diagnostics use the declaration keyword or type span, excluding matching words
in documentation and annotation arguments.
void f() {
var count = items.length; // flagged
final total = sum(items); // ok
}
Invalid
class Point {
final int x;
final int y;
Point(this.x, this.y);
}
int compute(List<int> items) {
var total = items.length;
int doubled = total * 2;
var a = 1, b = 2;
late var lazy = a + b;
return doubled + lazy;
}
void patterns((int, int) pair, Object o, List<(int, String)> rows) {
var (left, right) = pair;
print(left + right);
for (var (n, s) in rows) {
print('$n$s');
}
if (o case int value) {
print(value);
}
switch (o) {
case String text:
print(text);
case Point(x: var px):
print(px);
}
}
void closures() {
var shadowed = 1;
void inner(int shadowed) {
shadowed = 2;
print(shadowed);
}
inner(shadowed);
for (var i = 0; i < 3;) {
break;
}
}
String switchArms(Object o, (int, String?) pair) {
final label = switch (o) {
int v => '$v',
var other => '$other',
};
return switch (pair) {
(_, var text?) => text + label,
_ => label,
};
}int compute(List<int> items) { var total = items.length; var total = items.length; int doubled = total * 2; int doubled = total * 2; var a = 1, b = 2; var a = 1, b = 2; late var lazy = a + b;void patterns((int, int) pair, Object o, List<(int, String)> rows) { var (left, right) = pair; print(left + right); for (var (n, s) in rows) { print(left + right); for (var (n, s) in rows) { } if (o case int value) { switch (o) { case String text: print(text); case Point(x: var px):void closures() { var shadowed = 1; inner(shadowed); for (var i = 0; i < 3;) { final label = switch (o) { int v => '$v', int v => '$v', var other => '$other', return switch (pair) { (_, var text?) => text + label,Valid
int compute(List<int> items) {
final total = items.length;
const limit = 10;
var count = 0;
count += total;
var index = 0;
index++;
int? lazy;
lazy = count;
var a = 1, b = 2;
b = a;
for (var i = 0; i < limit; i++) {
count += i;
}
var _ = compute(items);
return count + (lazy ?? 0) + index + b;
}
void patterns((int, int) pair, Object o, List<(int, String)> rows) {
final (left, right) = pair;
var (first, second) = pair;
first = second;
var (_, _) = pair;
print(left + right + first);
for (final (n, s) in rows) {
print('$n$s');
}
for (var (n, s) in rows) {
n++;
print('$n$s');
}
if (o case final int value) {
print(value);
}
if (o case int value) {
value = 2;
print(value);
}
final label = switch (o) {
final int v => '$v',
_ => '',
};
print(label);
}
void closures() {
var captured = 1;
void inner() {
captured = 2;
}
inner();
print(captured);
var swapped = 1;
var other = 2;
(swapped, other) = (other, swapped);
print(swapped + other);
var loop = 0;
for (loop in [1, 2, 3]) {
print(loop);
}
}
// Patterns outside any function body are not reported.
final topLevelLabel = switch (Object()) {
int v => '$v',
_ => '',
};Configure prefer-final-locals
Set its severity in falcon.json. See the configuration guide.
{
"linter": {
"rules": {
"style": {
"prefer-final-locals": "error"
}
}
}
}Or silence one occurrence with a suppression comment; the reason is required.
// falcon-ignore lint/style/prefer-final-locals: <reason>More style rules
- prefer-final-parameters
prefer_final_parametersPrefer
finalfor parameters that are never reassigned. - prefer-first
prefer-firstFlags
[0]index access that should use the.firstgetter. - prefer-for-in
Flags zero-based, unit-step index loops over a syntactically known list.
- prefer-for-loop-in-childrenflutter
Prefers collection-for elements over eager map/toList chains in Flutter children.
- prefer-function-declarations-over-variables
prefer_function_declarations_over_variablesrecommendedFlags a local variable bound to a function literal that should be a local function declaration.
- prefer-generic-function-type-aliases
prefer_generic_function_type_aliasesrecommendedFlags old-style function typedefs written with inline parameter syntax.
- prefer-getter-over-method
Prefer getters for synchronous, zero-argument methods that only read a field.
- prefer-initializing-formals
prefer_initializing_formalsrecommendedPrefer initializing formals when a parameter is copied directly into its field.