Flutter의 Null Safety

blue·2023년 2월 27일
0

1. Nullable, non-nullable types

개발을 할 때 중요하지만 자주 신경쓰지 못하는 것 중 하나가 바로 null safety이다.
먼저 non-nullable type과 nullable type이 무엇인지 알아보자.

1.1. Non-nullable types

Non-nullable type이란 말 그대로 null 값을 가질 수 없는 타입을 의미한다.
대표적으로 String이 있는데, String 타입은 항상 문자열을 가지고 있어야 한다.
다음 코드는 int 타입을 선언했지만 null 값을 가질 수 없기에 오류가 발생한다.

  void main() {
    int a;
    a = null;
    print('a is $a.');
  }

1.2. Nullable types

Nullable type은 반대로 null 값을 가질 수 있는 타입을 의미한다.
Null 값을 가질 수 있음을 나타내는 것은 생각보다 간단한데, 바로 타입 바로 뒤에 물음표 (?)를 붙여주는 것이다.
다음 코드는 int? 타입을 선언했기에 null 값을 가질 수 있어 오류가 발생하지 않는다.

  void main() {
    int? a;
    a = null;
    print('a is $a.');
  }

1.3. Nullable type parameters for generics

generic 타입에 대해서도 동일한 방법으로 nullalbe type을 정의할 수 있다.
다음 코드는 List 자체가 null이기 때문에 List?으로 정의하면 오류가 발생하지 않는다.

  void main() {
  List<String>? aNullableListOfStrings;

  print('aNullableListOfStrings is $aNullableListOfStrings.');
  }

다음 코드는 List 안에 있는 String 타입 일부가 null이기 때문에 List<String?>으로 정의하면 오류가 발생하지 않는다.

  void main() {
  List<String?> aListOfNullableStrings = ['one', null, 'three'];

  print('aListOfNullableStrings is $aListOfNullableStrings.');
  }

2. Null assertion operator (!)

nullable한 타입이지만 null 값이 절대 들어가지 않을 것을 안다면, null assertion operator를 이용하여 non-nullable하다고 알려줄 수 있다.
이 방법 또한 간단한데, 뒤에 느낌표 (!)만 붙이면 된다.
다음 코드는 nullable한 타입으로 선언되었지만 null 값이 오지 않을 것이므로 !를 사용했다.

  int? couldReturnNullButDoesnt() => -3;

  void main() {
    int? couldBeNullButIsnt = 1;
    List<int?> listThatCouldHoldNulls = [2, null, 4];

    int a = couldBeNullButIsnt;
    int b = listThatCouldHoldNulls.first!; // first item in the list
    int c = couldReturnNullButDoesnt()!.abs(); // absolute value

    print('a is $a.');
    print('b is $b.');
    print('c is $c.');
  }

3. Null-aware operators

앞에서 어떤 값이 null이 아니라는 것을 알면 ! operator로 이를 표시할 수 있었다.
그러나 그럼에도 null이 오면 예외가 발생하므로 conditional property access operator와 null-coalescing operator 중 하나를 사용할 수 있다.

3.1. Conditional property access (?.)

nullable한 타입이 진짜 null인지 아닌지 확실하지 않다면, conditional property access를 사용할 수 있다. 이는 뒤에 ?. 을 붙여주면 된다.
다음은 nullableString 값이 null인지 알 수 없으므로 ?. 을 붙여 length에 접근했다.

  int? stringLength(String? nullableString) {
    return nullableString?.length;
  }

3.2. Null-coalescing operators (??)

nullable한 타입이 진짜 null인 경우, null-coalescing operator을 이용하여 대신 보여줄 다른 값을 지정할 수 있다.
이는 ?? 을 붙여준 뒤, 그 다음에 대신 보여줄 값을 넣으면 된다.
다음은 그 예시이다.

  print(nullableString ?? 'alternate');

4. late 키워드

late 키워드는 어떤 변수가 non-nullable해야하는데, 당장 값이 할당되지 않는 변수에게 사용된다.
이 키워드를 사용하면, 값을 나중에 할당할 것이고 해당 변수가 사용되기 전에 값을 무조건 가진다는 의미이다.
따라서 late 키워드와 함께 변수를 선언하면 에러가 throw된다.
다음은 late 키워드를 이용한 예시이다.

  class Meal {
    late String _description;

    set description(String desc) {
      _description = 'Meal description: $desc';
    }

    String get description => _description;
  }

  void main() {
    final myMeal = Meal();
    myMeal.description = 'Feijoada!';
    print(myMeal.description);
  }

5. 참고

https://dart.dev/codelabs/null-safety

0개의 댓글