Effective Dart: NULL in usage

MJ·2023년 6월 11일
0

Dart Basic

목록 보기
6/12

변수를 명시적으로 null로 초기화하지 않는다

  • 변수가 nun-nullable 타입을 초기화하지 전에 사용한다면, Dart는 컴파일 에러를 발생시킴
  • 변수가 nullable이라면, 암묵적으로 null로 초기화됨

    Dart에는 "초기화되지 않은 메모리"라는 개념이 없고 명시적으로 null로 초기화하지 않아도 괜찮음

Item? bestDeal(List<Item> cart) {
  // good case
  Item? bestItem;
  // bad case
  // Item? bestItem = null;

  for (final item in cart) {
    if (bestItem == null || item.price < bestItem.price) {
      bestItem = item;
    }
  }

  return bestItem;
}

매개변수에 기본 값으로 null을 명시하여 사용하지 않는다

  • 기본 값이 없는 nullable 매개변수를 사용하면, Dart는 해당 매개변수 기본 값을 암묵적으로 null로 사용하지 때문에 명시할 필요가 없다
// good case
void error([String? message]) {
  stderr.write(message ?? '\n');
}

// bad case
void error([String? message = null]) {
  stderr.write(message ?? '\n');
}

항등 연산자에 true 또는 false를 사용하지 않는다

  • 조건문 내의 non-nullable인 boolean 표현식을 평가 할 때, 항등 연산자를 쓰는 것을 불필요하며 필요하다면 단항 부정 연산자인 !를 사용하는 것이 좋다
// good case
if (nonNullableBool) { ... }
if (!nonNullableBool) { ... }

// bad case
if (nonNullableBool == true) { ... }
if (nonNullableBool == false) { ... }
  • Nullable인 boolean 표현식을 평가하고 싶으면 ?? 을 사용하거나 명시적으로 != null 확인을 해줘야한다
// good case
// 값이 null 일 때, 표현식이 false로 처리됨
if (nullableBool ?? false) { ... }

// 값이 null 일 때, 표현식이 false로 처리되고 아닐 때는 변수 값으로 처리
if (nullableBool != null && nullableBool) { ... }

// bad case
// 값이 null이라면 정적 에러 발생
if (nullableBool) { ... }

// 값이 null 일 때, false로 처리
if (nullableBool == true) { ... }

nullableBool == true는 실행 가능한 표현식이지만, 아래 이유로 사용하지 않는다

  • 코드가 null과 관련이 있음을 나타내지 않음
  • 명백히 null과 관련이 없기 때문에, 항등 연산자가 중복되어 제거될 수 있는 non-nullable의 경우로 쉽게 오인될 수 있다. 왼쪽의 boolean 표현식이 null일 가능성이 없을 경우에만 true이고, null을 생성할 수 있을 떄는 그렇지 않다
  • 해당 형식의 boolean 로직은 알아보기 힘들다. nullableBool이 null이라면, nullableBool == true는 조건식이 false로 평가된다는 것을 의미
    -> ?? 연산자롤 null이 발생할 수도 있는 상황에서 더 명확한 표현이 가능하고, 중복된 연산자로 헤깔릴 가능성이 줄어듬
    -> ?? 같은 null-aware 연산자를 조건식에 사용하는 것은 변수를 non-nullable 타입으로 반환하지 않음
    -> if문의 바디에서 변수의 타입을 변환하고 싶다면, ?? 보다 명시적으로 != null 확인하는 것이 좋다

초기화 여부를 확인해야하는 변수를 late로 선언하지 않는다

  • Dart는 late 변수가 초기화 또는 할당됭었는지 알 수 있는 방법을 가지고 있지 않음
  • late 변수에 접근 했을 때, initializer를 실행하거나, 예외를 발생
  • 바로 초기화할 변수에 late를 쓰는 것은 좋지만 아직 초기화를 하지 않았다면 알고 있어야 한다

타입 프로모션을 활성화하고 싶다면 지역 변수에 nullable 필드를 할당하는 것을 고려

  • Nullable 변수가 null이 아님을 판단할 때 변수를 non-nullable 타입으로 변환시키는 것도 좋다 (지역 변수와 매개변수에 대해서만 유효하므로 필드와 최상위 변수에는 불가)
class UploadException {
  final Response? response;

  UploadException([this.response]);

  
  String toString() {
    final response = this.response;
    if (response != null) {
      return 'Could not complete upload to ${response.url} '
          '(error code ${response.errorCode}): ${response.reason}.';
    }

    return 'Could not upload (no response).';
  }
}
profile
느긋하게 살자!

0개의 댓글