private 필드는 재할당하지 않으면 final로 선언해요
private 필드는 재할당하지 않으면 final로 선언해요
prefer_final_fields 린트 규칙은 나중에 재할당하지 않는 private 필드는 final로 선언하라고 권하는 규칙이에요. Stable 상태이고 공식 추천(Recommended) 규칙이며 자동 수정도 가능해요.
본문
Effective Dart에서도 나오는 규칙이에요. 라이브러리 안에서 나중에 재할당되지 않는 private 필드는 final로 선언하세요.
필드를 가능하면 final로 선언하는 게 좋은 습관인 이유는, 실수로 값을 다시 바꾸는 일을 막아 주고 컴파일러가 최적화를 할 수 있게 해 주기 때문이에요.
BAD — 재할당하지 않는데 var로 선언했어요.
class BadImmutable {
var _label = 'hello world!'; // LINT
var label = 'hello world!'; // OK
}
BAD — 여러 필드 중 일부만 final이고 나머지엔 린트가 걸려요.
class MultipleMutable {
var _label = 'hello world!', _offender = 'mumble mumble!'; // LINT
var _someOther; // LINT
MultipleMutable() : _someOther = 5;
MultipleMutable(this._someOther);
void changeLabel() {
_label = 'hello world!';
}
}
GOOD — 재할당하지 않는 필드는 전부 final로 선언했어요.
class GoodImmutable {
final label = 'hello world!', bla = 5; // OK
final _label = 'hello world!', _bla = 5; // OK
}
GOOD — 실제로 값을 바꾸는 필드라면 var로 남겨도 괜찮아요.
class GoodMutable {
var _label = 'hello world!';
void changeLabel() {
_label = 'hello world!';
}
}
BAD — 모든 생성자에서 값을 할당하는 필드도 사실상 재할당이 아니에요.
class AssignedInAllConstructors {
var _label; // LINT
AssignedInAllConstructors(this._label);
AssignedInAllConstructors.withDefault() : _label = 'Hello';
}
GOOD — 초기화 없이 선언만 하고 생성자에서만 값을 정하는 필드는 var라도 괜찮아요.
class NotAssignedInAllConstructors {
var _label; // OK
NotAssignedInAllConstructors();
NotAssignedInAllConstructors.withDefault() : _label = 'Hello';
}
규칙 켜기
analysis_options.yaml 파일의 linter > rules 아래에 prefer_final_fields를 추가하면 돼요.
linter:
rules:
- prefer_final_fields
YAML 맵 문법으로 설정한다면 이렇게 써요.
linter:
rules:
prefer_final_fields: true
더 알아보기
- 선언 시점에 값을 알 수 없는 필드(생성자에서만 값이 정해지는 필드)는
final로 쓸 수 없으니var로 남겨요.