값이 채워지기 전에 쓰인 non-nullable 지역 변수
값이 채워지기 전에 쓰인 non-nullable 지역 변수 (not_assigned_potentially_non_nullable_local_variable)
Dart의 non-nullable 안전성과 관련된 진단이에요. 지역 변수가 non-nullable 타입인데, 어느 시점에 어떤 값도 대입되지 않은 채로 쓰이고 있다는 뜻이에요. 메시지는 "The non-nullable local variable '{0}' must be assigned before it can be used." — "non-nullable 지역 변수 '{0}'은(는) 사용되기 전에 값이 반드시 대입되어야 해요"라고 알려줘요.
본문
언제 발생하나요?
애널라이저가 지역 변수의 참조를 검사하다가 이 변수가 아래 성질을 전부 갖고 있으면 이 진단을 내요.
- 타입이 non-nullable이에요.
- 초기화식(initializer)이 없어요.
late로 표시되지 않았어요.- 그리고 애널라이저가 정확한 대입 분석(definite assignment analysis)에 기반해서, 해당 참조 지점 전에 값이 대입된다는 걸 증명하지 못해요.
non-nullable 변수는 null이 될 수 없으니, 어떤 경로로든 사용 전에 반드시 값이 채워져 있어야 해요. 그걸 보장하지 못할 때 이 진단이 나오는 거예요.
예시
다음 코드는 x가 null 값을 가질 수 없는데, 값이 대입되기 전에 참조되고 있어서 이 진단이 발생해요.
String f() {
int x;
return x.toString();
}
다음 코드는 x에 대한 대입이 실행되지 않을 수도 있어서, x가 null일 수 있기 때문에 진단이 발생해요.
int g(bool b) {
int x;
if (b) {
x = 1;
}
return x * 2;
}
다음 코드는 애널라이저가 대입 분석(definite assignment analysis)으로 x가 값 없이 참조되지 않는다는 걸 증명할 수 없어서 진단이 발생해요.
int h(bool b) {
int x;
if (b) {
x = 1;
}
if (b) {
return x * 2;
}
return 0;
}
두 번째 if (b) 블록 안에서 x * 2가 참조되는 시점에 x에 값이 들어 있다는 걸 스스로 따져보면 애매한 부분이 남는 걸 알 수 있어요. 첫 번째 if (b)가 실행되지 않았다면 x는 여전히 빈 상태니까요.
어떻게 고치나요?
null이 타당한 값이라면, 변수를 nullable 타입으로 바꿔요.
String f() {
int? x;
return x!.toString();
}
null이 타당하지 않고, 합리적인 기본값이 있다면 초기화식을 추가해요.
int g(bool b) {
int x = 2;
if (b) {
x = 1;
}
return x * 2;
}
그게 아니라면, 값이 접근되기 전에 모든 코드 경로에서 값이 대입되도록 보장해요.
int g(bool b) {
int x;
if (b) {
x = 1;
} else {
x = 2;
}
return x * 2;
}
변수를 late로 표시할 수도 있어요. 그러면 이 진단은 사라져요. 다만 값이 대입되기 전에 접근하면 런타임에서 예외가 던져지거든요. 애널라이저가 대입 분석으로 증명할 수는 없지만, 당신 자신이 "항상 값이 대입될 거야"라고 확신할 수 있을 때만 이 방법을 쓰는 게 좋아요.
int h(bool b) {
late int x;
if (b) {
x = 1;
}
if (b) {
return x * 2;
}
return 0;
}
더 알아보기
- non-nullable 안전성 전반은 Null safety 문서에서 확인할 수 있어요.
- 다른 진단과 함께 보려면 Diagnostics 목록을 참고하세요.