이번 포스팅에선 Flutter의 Null Safety에 대해 소개하겠다.
예시 코드를 통해 자세히 알아보자.
소개
Null Safety는 Flutter 2.12 버전부터 도입된 기능이다.
코드의 안정성과 신뢰성을 높이는 도구로써 개발되었다.
Null Safety의 주요 개념은 변수의 널 (null) 가능성을 명시적으로 표시하는 것이다.
이를 통해 런타임 중에 발생할 수 있는 널 참조 오류를 사전에 방지할 수 있다.
예시 코드
예시 코드를 통해 Null Safety의 사용법을 살펴보자.
// 널 안전성이 없는 코드 (Null Safety 비활성화)
String name; void main() {
name = null; // null 값을 할당할 수 있음
print(name.length); // 런타임에서 오류 발생 (Null 참조)
}
위 코드는 Null Safety를 비활성화한 상태에서 실행되는 예시다. 변수 name은 널 값이 들어갈 수 있기 떄문에 위험하다.
그래서 만약, Null 값을 넣고 name.length를 출력하려고 할 때, 런타임에서 Null 참조 오류가 발생한다.
이제 Null Safety를 활성화하면 어떻게 되는지 살펴보자.
// 널 안전성이 있는 코드 (Null Safety 활성화)
String? name; void main() {
name = null; // null 값을 할당할 수 있음
print(name.length); // 컴파일 타임에서 오류 발생 (Null 참조)
}
보다시피, 위 코드에서는 변수 name의 타입 뒤에 물음표(?)를 붙여 널 가능성을 표시한다.
이제 name.length를 출력하려고 할 때, 컴파일 타임에서 Null 참조 오류가 발생한다.
이는 Null Safety를 통해 컴파일 타임에서 오류를 확인하여 프로그래머가 오류를 사전에 발견하고 수정할 수 있도록 보조한다.
또한, Null Safety는 null 값을 다룰 때 추가적인 작업을 요구한다.
예를 들면, null 값이 아닌지 확인한 후에 사용하거나 null 병합 연산자(??)를 사용하여 기본값을 지정할 수 있습니다.
Null Safety는 코드 작성 시 불안정한 null 값으로 인한 오류를 줄이고, 코드의 안정성을 높이는 데 큰 도움이 된다.
! 연산자
이런 코드를 본 적이 있는가?
String nonNullableName = name!;
! 연산자가 달려있다. 이는 Null Safety가 활성화된 코드에서
Nullable 타입의 변수를 Non-nullable로 강제 변환하는 역할을 한다.
Nullable 타입은 해당 변수가 null 값을 가질 수 있음을 의미하는데,
이러한 변수를 사용할 때는 null check를 통해 안전하게 사용해야 한다.
그러나 때로는 변수가 null이 아님을 확신할 때도 있다.
이때 ! 연산자를 사용하여 해당 변수를 Non-nullable로 변환할 수 있는 것이다.
예를 들어,
String? name;
위 코드에서 name 변수는 Nullable 타입이다. 따라서 name 변수를 사용할 때는 null 체크를 해야 한다.
그러나 사용자가 name 변수가 null이 아님을 이미 알고 있다면 ! 연산자를 사용하여
강제로 Non-nullable로 변환할 수 있다.
String nonNullableName = name!;
위 코드에서 name!은 name 변수가 null이 아님을 명시적으로 나타내는 것이다.
따라서 nonNullableName은 Non-nullable 타입인 String으로 선언되어 null 값이 들어갈 수 없게 된다.
이런 예시도 있다.
String? name;
String showName;
void main() {
name = "전꽃비";
showName = name!;
print(showName); // 출력: 전꽃비
name = null;
showName = name!; // Null check operator used on a null value 오류 발생
}
String? 타입의 nullable name 변수와 non-nullable showName 변수가 있다.
name이 null이 아닐 것을 알기 때문에 ! 연산자를 사용하여 강제로 변환할 수 있다.
main 함수에서는 먼저 name 변수에 "전꽃비"를 할당한다.
name이 null이 아니기 때문에 ! 연산자를 사용하여 그 값을 showName에 안전하게 할당할 수 있다.
하지만 나중에 name 변수에 null을 할당하고 null 체크 없이 showName을 출력하려고 하면, "Null check operator used on a null value" 오류가 발생한다. 이는 name이 null이 아니라고 가정했지만 실제로는 null인 경우를 가진다.
! 연산자를 사용할 때는 변수가 사용되는 지점에서 실제로 null이 아님을 보장해야 하므로 null 참조 오류를 피하기 위해 주의해야 한다.
해체를 사용하지 않고 ! 연산자를 사용한다면, person 변수에 값이 할당된 상태에서는 ! 연산자를 사용하여 값을 할당하는 것이 안전하다. 그러나 person을 null로 할당한 후에 ! 연산자를 사용하여 값을 가져오려고 하면 동일한 "Null check operator used on a null value" 오류가 발생한다. 이는 null이 아니라고 가정했지만 실제로는 null인 경우이다.
주의해야하는 점
! 연산자를 남발하면 Null Safety의 사용하는 의미가 퇴색된다.
! 연산자를 사용할 때는 해당 변수가 실제로 null이 아닌 경우에만 사용해야 한다.
그렇지 않으면 Null 참조 오류가 발생할 수 있다.
세줄 요약
1. Dart 에서는 ? 연산자를 활용한 Null Safety 라는 것이 있다. 이는 Nullable 변수로 만들어 런타임 에러를 방지한다.
2. Dart에서 ! 연산자는 Null Safety 코드에서 Nullable 타입의 변수를 Non-nullable로 강제 변환하는 역할을 한다.
하지만 신중하게 사용해야 하며, null 체크를 제대로 수행하지 않은 상황에서 남발하면 코드의 안전성이 떨어질 수 있다,
3. Dart의 Null Safety에 대한 간단한 소개와 예시 코드를 만들어보았다.
4. Null Safety는 안전성, 신뢰성이 검증된 코드 작성을 위한 강력한 도구인 만큼,
새로운 프로젝트나 기존 프로젝트에서 활용해보기를 권장한다.