[Dart/Flutter] null check와 null safety
개발을 하다보면 null 객체에 접근하여 에러가 발생하는 일이 많습니다. 이 에러를 피하기 위해 null check 코드를 추가하여 예외처리를 하게 되는데요. null check 코드를 넣다보면 어느새 매우 많은 null check로 코드가 길어지고 지저분해지기도 합니다.
이 글은 Dart에서 null check를 하는 방법과 Dart에서 지원하는 null safety(null 안정성)에 대해서 소개하려고 합니다.
1. if문과 삼항연산자로 null check
다른 언어와 동일하게 if문으로 다음과 같이 null check를 할 수 있습니다.
if (variable != null) {
// null이 아닌 경우
} else {
// null인 경우
}
또는, 다음과 같이 삼항연산자를 사용하여 어떤 값이 null이면 default로 다른 값을 입력하도록 구현할 수도 있습니다.
void main() {
String? variable = null;
String defaultVal = "default value";
var newString = (variable != null) ? variable : defaultVal;
print(newString); // default value
}
2. null-aware 연산자(??)로 null check
Dart에서는 ??
라는 null-aware 연산자를 제공하며, 위의 삼항연산자 예제처럼 null check를 할 수 있습니다.
- variable이 null 인 경우, defaultVal을 newString에 대입
- variable이 null이 아닌 경우, variable을 newString에 대입
void main() {
String? variable = null;
String defaultVal = "default value";
var newString = variable ?? defaultVal;
print(newString); // default value
}
3. 메소드에서 null-aware 연산자(.?)
메소드에서도 null-aware 연산자를 사용할 수 있는데, variable?.toString()
는 variable이 null일 때 null을 리턴하며, null이 아니면 toString()
메소드의 결과를 리턴합니다.
?.
를 사용하면 전통적인 null check 코드(if 같은)를 줄여 코드 가독성을 높일 수 있습니다.
void main() {
String? variable = null;
String defaultVal = "default value";
var newString = variable?.toString();
print(newString); // null
}
만약 variable가 null이면 variable?.toString()
이 null을 리턴하게 되는데, null 대신 다른 값을 전달하게 만드려면 아래와 같이 ??
를 함께 사용하면 됩니다.
variable?.toString()
에서 null이 리턴되어 ??
로 "default value"
가 리턴됩니다.
void main() {
String? variable = null;
String defaultVal = "default value";
var newString = variable?.toString() ?? "default value";
print(newString); // default value
}
4. null safety (null 안정성)
Dart의 변수는 기본적으로 non-null 변수로, null을 대입하려고 하면 컴파일 에러가 발생합니다. 따라서 Runtime에 발생하는 문제를 컴파일 타임에 찾고 해결할 수 있습니다.
예를 들어, 아래와 같이 null일 입력하려고 하면
String variable = null;
아래와 같은 에러가 발생합니다.
bin/dart_application_1.dart:2:21: Error: The value 'null' can't be assigned to a variable of type 'String' because 'String' is not nullable.
String variable = null;
null을 입력하고 싶다면 타입에 ?
를 추가해야 합니다.
String? variable = null;
다른 예제로, 타입이 맞지 않는 경우 컴파일 에러가 발생하는데, 아래 예제의 int?
와 int
처럼 null을 허용하는 타입과 허용하지 않는 타입을 구분하여 컴파일 에러를 발생시킵니다.
int sum(int a, int b) {
return a + b;
}
void main() {
int a = 10;
int? b = null;
int result = sum(a, b);
print(result);
}
Output:
/home/mjs/blog-code/dart-example/dart_application_1/bin/node_48e9d556665c7.tmp.js:1
int sum(int a, int b) {
^^^
SyntaxError: Unexpected identifier
at internalCompileFunction (node:internal/vm:74:18)
at wrapSafe (node:internal/modules/cjs/loader:1141:20)
at Module._compile (node:internal/modules/cjs/loader:1182:27)
at Module._extensions..js (node:internal/modules/cjs/loader:1272:10)