티스토리 뷰
Dart는 컴파일 과정에서 Null Point Exception을 잡아서 런타임 에러가 덜 발생할 수 있도록 해주는 개념이다.
즉, 변수 자체가 선언 과정에서 초기화되지 않거나, null 값을 가지면 컴파일러가 바로 에러를 잡아낼 수 있다.
Dart에서 처음 접해보는 개념이지만, 그렇게 어렵지도 않고 사용하기는 편리하니 바로 한번 확인을 해보자.
* 이번 포스팅은 null safety에 대하여 아주 자세하게 정리한 블로그에서 참고하였다.
1. Nullable과 Non-Nullable
Null Safety 가 지원이 되려면 가장 기본적으로 변수 선언 시 Nullable과 Non-Nullable로 구분되어 선언해 주어야 한다.
Dart 언어의 변수는 기본이 Non-Nullable 로 선언되는 것이며 만악 Nullable로 선언하고자 한다면 타입명 뒤에? 를 추가해 주어야 한다.
int a1=10;
int? a2=10;
a1 은 int 로 선언되어 있으며 a2는 int?로 선언되어 있다.
모두 정수 데이터를 저장하기 위한 타입으로 선언된건 맞지만? 가 있고 없고의 차이는 Null Safety에서 큰 차이가 있다.
int로 선언되면 이 변수에는 null 대입이 불가능한 Non-Nullable로 선언된 것이며 int?로 선언하면 이 변수에는 null 대입이 가능한 Nullable로 선언된 것이다.
int a1=10;
int? a2=10;
testFun() {
a1=null;//error
a2=null;
}
2. Null Safety 규칙
Null Safety 개념이 이해 되었다면 이제 몇 가지 규칙을 추가 정리해 보자.
1) Non-Nullable 변수는 선언과 동시에 초기값을 주어야 한다.
int a1;//error
int? a2;
Dart 에서 모든 변수는 객체이다.
그런데 변수를 선언하면서 초기값을 주지 않으면 null로 자동 초기화된다.
하지만 Non-Nullable 로 선언된 변수는 null로 자동 초기화된다는 것은 말이 안 되기 때문에, Non-Nullable 선언된 변수는 선언과 동시에 명시적으로 초기값을 주어야 한다.
2) var 타입에서의 Null Safety
Dart 에서 변수 선언 시 타입을 var로 선언하여 타입을 유추하도록 할 수 있다.
즉, var 로 타입 선언 시 Nullable과 Non-Nullable도 자동 유추가 되기 때문에 var 타입 뒤에는? 를 추가할 수 없다.
var a1=10;
var a2=null;
var a3;
var? a4=null;//error
3) dynamic 타입에서의 Null Safety
dynamic 타입에는 ? 가 추가되어 선언될 수 있지만 의미가 없다.
dynamic 타입이 대입되는 값을 한정하지 않겠다는 의미이며 모든 타입의 데이터가 대입될 수 있다는 의미이다.
여기에는 Nullable도 포함이 되기 때문에 dynamic 타입으로 선언되는 것 자체가 Nullable 로 선언되는 것이다.
dynamic a1 = 10;
dynamic a2;
dynamic? a3;
testFun() {
a1=null;
a2=null;
a3=null;
}
4) Local Variable 에서만 Non-Nullable 변수가 선언과 동시에 초기화되지 않아도 된다.
? 가 추가되지 않아 Non-Nullable 로 선언된 변수는 null 대입이 불가함으로 선언과 동시에 초기값을 주어야 한다.
하지만 이는 Top-Level 에 선언된 변수와 클래스 멤버 변수의 규칙이며 함수 내에 선언되는 Local Variable 은 변수가 Non-Nullable로 선언되었다고 하더라도 선언과 동시에 초기값을 주지 않아도 된다.
testFun() {
int a1;
a1=10;
print(a1+10);//ok
}
5) casting Test
Nullable 로 선언된 변수가 Non-Nullable로 선언된 변수에 대입이 가능한지, 반대로 Non-Nullable로 선언된 변수가 Nullable로 선언된 변수에 대입이 가능한지를 확인해보면, 타입적으로 Nullable 변수는 Non-Nullable 변수의 상위 타입이기 때문에 int? 타입이 int 타입의 상위 타입이 된다.
그럼으로 Non-Nullable 변수가 Nullable에 대입되는 것은 스마트 캐스팅에 의해 자동으로 형 변형이 된다.
하지만 Nullable 변수가 Non-Nullable 에 대입되는 것은 에러이며 하고자 한다면 명시적 캐스팅을 사용해 주어야 한다.
int a1=10;
int? a2=10;
main() {
a1=a2;//error
a2=a1;//ok
}
a1 은 Non-Nullable 로 선언되어 있으며 a2는 Nullable로 선언되어 있다.
a1 이 a2 에 대입되는 데는 문제가 없지만 a2 가 a1에 대입되면 에러가 발생하게 되며 가능하게 하려면 아래의 코드처럼 명시적 캐스팅을 해주어야 한다.
int a1=10;
int? a2=20;
main() {
a1=a2 as int;//ok
print("a1: $a1, a2: $a2");//a1: 20, a2: 20
}
* Dart 에서 명시적 캐스팅 연산자는 as이다.
3. Null Safety Operator
1)!: null check operator — runtime error throw
어떤 변수 뒤에! 을 추가하면 이 변수 값이 null 인 경우 runtime error 발생하게 된다.
int? a2=20;
main() {
a2!;
a2=null;
a2!;
}
위의 코드를 실행시켜 보면 마지막 라인에서 런타임 에러가 발생하게 된다.
! operator 은 nullable variable을 non-nullable에 대입할 때도 사용이 가능하다.
int a1=10;
int? a2=20;
main() {
// a1=a2;//compile error
a1 = a2 as int;//ok
a1=a2!;
print('step 1 : a1 = $a1');//step 1 : a1 = 20
a2=null;
a1=a2!;//runtime error
print('step 2 : a1 = $a1');
}
2) late keyword
non-nullable로 변수가 선언되면 선언과 동시에 초기값을 주어야 한다.
그런데 어떤 경우에는 변수가 non-nullable로 선언되기는 하지만 선언과 동시에 초기값을 줄 수 없는 경우도 있다.
즉, 변수가 null 인 상태로 이용되지는 않지만 초기값이 앱이 실행되면서 결정되는 경우이다.
이때 late keyword를 사용하면 된다.
late는 단어 뜻 그대로 초기화 시점을 뒤로 미루겠다는 의미이다.
int a1;//compile error
late int a2;//ok
'Mobile > Dart' 카테고리의 다른 글
[Dart] 비동기 프로그래밍: future, async, await (0) | 2022.06.27 |
---|---|
[Dart] factory (0) | 2022.06.26 |
[Dart] Extends, Implements, With (0) | 2022.06.26 |
[Dart] Dart 기본 (0) | 2022.06.26 |
- 파니노구스토
- react-native
- redux
- await
- Promise
- AsyncStorage
- 맛집
- react
- redux-thunk
- 이탈리안 레스토랑
- Async
- 인천 구월동 이탈리안 맛집
- 인천 구월동 맛집
- 정보보안기사 #실기 #정리
- javascript
- Total
- Today
- Yesterday