배운것들을 정리합니다.
三昧境

Flutter/Dart Language

[플러터 Flutter] Null-Safety와 late키워드

ujo_orr 2024. 6. 29. 00:52

NullSafety는 Dart에서 도입된 개념입니다.
코드에서 null 참조에 대한 안정성을 높이기 위한 기능이며
이를 통해 null 참조로 인한 예기치 않은 오류를 방지하고 안전한 코드를 작성할 수 있습니다.

똑같이 ?(Question mark)를 사용해도 삼항연산자와는 다른 개념입니다.


Null-Safety의 주요 개념

 

Nullable 타입

변수가 null을 포함할 수 있는 타입입니다.
변수를 선언할 때 String이 아닌 String? 으로 작성합니다.

String? nullableName;
String nullavleName; // 오류

 


 

Non-nullable 타입

변수가 null을 포함할 수 없는 타입입니다.
이는 변수를 선언할 때 String? 이 아닌 String 으로 작성합니다.

String name = 'John Doe';
String? name = 'John Doe'; // 오류아님. name변수가 null을 가질수 있음을 의미 (Null-safety)

 

 

 


 

Null-aware 연산자

null일 수 있는 변수에 접근할 때 사용하는 연산자로 변수에 접근할 때 사용하는 연산자입니다.
?. / ?? / ! 키워드가 있습니다.

void main() {
  String? nullableName; // nullable 변수
  
  // Safe navigation operator (?.)
  int length = nullableName?.length ?? 0; // nullableName이 null이면 0을 반환
  
  // null 체크
  if (nullableName != null) {
    print(nullableName.length); // nullableName이 null이 아닐 때만 접근
  }

 

• ! : Non-nullable 변수를 nullable로 강제 변환할 때 사용합니다. 이는 변수가 null일 수 없다고 확신할 때 사용됩니다.

String? nullableString;
String nonNullableString = nullableString!;

?. : null-safe navigation 연산자로, null일 가능성이 있는 변수에 접근할 때 사용합니다.

String? nullableName; // nullable 변수
  
int length = nullableName?.length ?? 0; // nullableName이 null이면 0을 반환

?? : null-aware 연산자로, null일 경우 대체값을 지정할 때 사용합니다.

String? nullableString;
String nonNullableString = nullableString ?? 'default value';

 

late 변수

나중에 초기화되는 변수로, null을 할당할 수 없으며 초기화하기 전까지 변수를 사용할 수 없습니다.
현재는 변수명만 선언하고 그 내부에 값은 말 그대로 나중에 주겠다는 뜻입니다.

class MyLate {
  late String lateString; // String값 지정안됨

  void initialize() {
    lateString = '늦었습니다'; //이 시점에 String값 지정됨
    print(lateString);
  }

void main() {
  var myLate = MyLate(); // Dart의 타입추론
  // MyLate myLate = MyLate(); 와 같은 기능 //명시적 타입 지정
  myObject.initialize(); // 출력: 늦었습니다
}

 

그렇다면

late String lateString;
late String? lateString;
String? lateString;

이 세 개의 코드도 잘 읽어보면 달리 해석할 수 있습니다.

1. late String lateString;

초기화(변수가 호출되는 시점) 전에 변수를 사용할 수 없습니다.
변수를 처음 접근할 때 반드시 초기화가 되어야 하고 만약 초기화되지 않은 상태에서 접근하려고 하면 런타임 오류가 발생합니다.

late String lateString;

void initialize() {
  lateString = 'Hello, World!';
}

void main() {
  initialize();
  print(lateString); // 출력: Hello, World!
}

 

2. late String? lateStirng;

초기화전에 변수를 사용할 수 있습니다.
초기화되지 않은 상태에서는 null값을 가질 수 있습니다.

late String? lateString;

void initialize() {
  lateString = 'Hello, World!';
}

void main() {
  print(lateString); // 출력: null (초기화 전에 접근)
  initialize();
  print(lateString); // 출력: Hello, World!
}

 

3.  String? lateStirng;

초기화되지 않은 상태에서 null값을 가질 수 있습니다.
late 키워드를 사용하지 않으므로 언제든지 null로 초기화될 수 있습니다.

String? lateString;

void initialize() {
  lateString = 'Hello, World!';
}

void main() {
  print(lateString); // 출력: null (초기화 전에 접근)
  initialize();
  print(lateString); // 출력: Hello, World!
}

 

이 세 가지 선언문은 null-safety와 초기화 시점에 따라 다르게 동작합니다.
각 상황에 맞게 적절한 방법을 선택해서 사용하면 됩니다.