Null : 아직 값이 정해지지 않은 것
void whatIsYourFood(Food f) { if (f == null) print('need a food name'); else print(f.recipe.toString()); }
만약 f의 값이 null 이라면 다음 소스코드와 같이 if 문에서 null 검사를 해주면 된다.
그러면 굳이 flutter 에서 null safety 를 사용하는 이유가 무엇일까?
개발자가 실수로 if문에서 null 검사를 해야함을 잊을 수 있기 때문이다.
flutter는 이런 실수의 가능성을 없애기 위해 null safety를 사용한다.
이제 null safety에 대해 정리해보자.
non-nullable 변수에 null을 할당할 수 없다.
void main() { String name; int age = null; print(name); print(age); }
null safety가 적용되기 이전에는 이 소스코드에 아무런 오류가 나지 않고, null이 잘 출력되었지만,
이제 변수에 null값이 할당될 수 없다.
non-nullable 변수를 위한 null check가 필요하지 않다.
int number = 4; void main() { if (number == null) return; int sum = number + 5; print(sum); }
다음과 같은 코드를 짰을 때, int는 null-nullable하므로 null값을 걸러줄 필요가 없다는 문구가 뜨게된다.
하지만
Food favorite = null 다음과 같이 가장 좋아하는 음식이 아직 없는 경우를 표현할 때는 null값이 필요하다.
또는 변수를 선언할때에는 당장 값이 할당되지 않아도, 나중에 할당될 수 있게 코드를 짜기도 한다.
우리는 아직 변수에는 null 값이 할당될 수 없다고 알고 있으므로, null 값을 표현하지 못한다는 단점이 생긴다.
때문에 nullable type이 있다.
기존의 변수 타입에 String? 와 같이 ?를 붙여서 null을 할당할 수 있고,
사용하기 전에 꼭 null check를 해서 사용해야한다.
또는 null assertion 연산자인 !를 사용해서
안전하지 않지만, null이 확실하지 않다는 가정하에 null check없이 사용할 수도 있다.
!를 사용하면 String? 타입 변수를 String으로 바꿔서 쓰는것과 같다.
'Class 내의 변수'는 반드시 선언과 동시에 초기화해야한다.
class Person() { String name; String nameChange(String name) { this.name = name; return name.toUpperCase(); } } void main() { Person p = Person(); if (p.name == null) print('need a name'); else print(p.nameChange(p.name)); }
null safety 적용 전에는 다음과 같은 소스코드에 아무런 문제가 없었지만,
개발자가 많은 수의 변수를 다루다보면 null 검사를 잊을 수 있다는 문제가 생긴다.
때문에 null safety가 적용되면서 컴파일 과정에서 name은 선언과 동시에 초기화 해야하고, null검사가 의미없다는 문구가 나온다.
이를 해결하기 위해서는 3가지의 방법이 있다.
- require 키워드 사용
- late 키워드 사용
- ?을 붙여 Nullable 타입으로 변환 후 null 체킹 하면서 사용