null일 수 있는 값을 확인 없이 사용하기

null일 수 있는 값을 확인 없이 사용하기

Dart 분석기(analyzer)가 내보내는 진단 중 하나인 unchecked_use_of_nullable_value를 다뤄볼게요. 이 진단은 값이 null일 수 있는 상황인데도 그 값을 확인 없이 사용하려고 할 때 나타나요. 코드가 컴파일되더라도 런타임에 예기치 않은 문제가 생길 수 있으니, 어떤 상황에서 발생하고 어떻게 고치면 좋은지 함께 살펴볼게요.

출처: unchecked_use_of_nullable_value

본문

이 진단은 다음과 같은 메시지로 나타나요.

  • A nullable expression can't be used as a condition. (null일 수 있는 표현식은 조건으로 쓸 수 없어요.)
  • A nullable expression can't be used as an iterator in a for-in loop. (null일 수 있는 표현식은 for-in 루프의 반복자로 쓸 수 없어요.)
  • A nullable expression can't be used in a spread. (null일 수 있는 표현식은 spread에 쓸 수 없어요.)
  • A nullable expression can't be used in a yield-each statement. (null일 수 있는 표현식은 yield-each 문에 쓸 수 없어요.)
  • The function can't be unconditionally invoked because it can be 'null'. (null일 수 있기 때문에 함수를 무조건 호출할 수 없어요.)
  • The method '{0}' can't be unconditionally invoked because the receiver can be 'null'. (수신자가 null일 수 있어서 메서드 '{0}'를 무조건 호출할 수 없어요.)
  • The operator '{0}' can't be unconditionally invoked because the receiver can be 'null'. (수신자가 null일 수 있어서 연산자 '{0}'를 무조건 호출할 수 없어요.)
  • The property '{0}' can't be unconditionally accessed because the receiver can be 'null'. (수신자가 null일 수 있어서 프로퍼티 '{0}'에 무조건 접근할 수 없어요.)

설명

분석기는 null일 가능성이 있는(potentially non-nullable) 타입의 표현식을, 값이 null이 아닌지 먼저 확인하지 않고 역참조(dereference)할 때 이 진단을 내보내요. 잠재적으로 non-nullable하다는 건, 명시적으로 null이 아닌 타입이거나 타입 매개변수라서 null일 수도 있는 타입이라는 뜻이에요.

예시

아래 코드는 s가 참조되는 시점에 null일 수 있기 때문에 이 진단이 발생해요.

void f(String? s) {
  if (s.length > 3) {
    // ...
  }
}

자주 쓰는 해결 방법

값이 실제로 null일 수 있다면, 값이 null이 아닐 때만 멤버에 접근하도록 검사를 추가해요.

void f(String? s) {
  if (s != null && s.length > 3) {
    // ...
  }
}

표현식이 변수이고 그 값이 절대 null이 되면 안 되는 경우라면, 변수의 타입을 non-nullable로 바꿔요.

void f(String s) {
  if (s.length > 3) {
    // ...
  }
}

표현식의 값이 절대 null이 되어선 안 된다고 믿지만 변수의 타입을 바꿀 수 없고, 설령 틀려서 런타임에 예외가 던져져도 괜찮다면, 값이 null이 아님을 단언(assert)할 수도 있어요.

void f(String? s) {
  if (s!.length > 3) {
    // ...
  }
}

더 알아보기