Flutter 3주차 - 널 안정성(null safety)

2024. 9. 22. 17:10flutter

Flutter 3주차 - 널 안정성(null safety)

 

이번 주차에서는 Flutter로 앱을 개발하기 전, 널 안정성의 개념에 대해 이해해보는 시간을 가져보려 한다.

 

코드는 웹사이트에서 간단하게 실행할 수 있는 https://dartpad.dev/ 에서 테스트할 예정이다.

 

 

목차

     

     

    널 안정성이란?

     

    널 안정성(null safety)은 널 포인트 예외(NPE: null point exception)를 프로그램을 실행하기 전 코드를 작성하는 시점에 점검하는 것을 의미한다.

     

     

    NPE 발생 가능성을 컴파일러가 미리 점검해 주므로 널에 안전한 코드를 작성할 수 있게 되었다.

    플러터 2.0이 나오면서 다트언어가 2.12.0 버전으로 업데이트되었고, 이후 널 안정성을 지원하기 시작했다.

     

    pub.dev 에서 널 안정성 지원여부를 확인할 수 있다.

     

     

     

    널 허용과 널 불허

     

    변수를 선언할 때 널 허용(Nullable)과 널 불허(NonNull)로 구분하여 선언할 수 있다.

     

    다트 언어에서 변수는 기본적으로 널 불허로 선언하는데, 널 허용으로 선언하고 싶다면 타입 뒤에 물음표 '?' 를 추가하여 선언하면 된다.

     

     

     

     

    아래 예제를 보면 a1은 널 불허로 선언했고, a2는 널 허용으로 선언했으므로 a1에 null 값을 넣으려고 하면 에러가 난다.

     

     

     

     

    int 타입 외에 다른 모든 타입에서도 똑같이 널 허용 설정이 가능하다.

     

     

     

     

    var 타입의 널 안정성

     

    var로 선언한 변수는 널 허용 여부도 대입하는 값에 따라 컴파일러가 자동으로 결정한다.

     

    아래 예제를 보면 이해하기 쉽다.

     

     

    var 타입 변수에 물음표를 붙이면 에러가 발생한다.

     

     

    var 변수에 null을 대입하면 dynamic 변수가 된다.

     

     

     

     

    dynamic 타입의 널 안정성

     

    dynamic 타입은 모든 타입의 데이터를 대입할 수 있으므로 널을 허용하는 Nullable도 포함한다.

     

     

     

     

    널 안정성과 형 변환

     

    Nullable은 NonNull의 상위 타입이다.

     

    아래 예제와 같이 Nullable 변수(a2)에 NonNull 변수(a1)가 포함될 수 있지만, NonNull 변수(a1)에 Nullable(a2) 변수가 포함될 수 없다.

     

     

     

     

    다트에서 명시적 형 변환 연산자는 as를 사용하면 된다.

     

     

     

     

    초기화를 미루는 late 연산자

     

    late는 초기화를 미루는 연산자이다.

     

    보통 NonNull 변수는 선언할 때 초기화를 같이 해줘야 하지만 초기화를 하기 애매한 상황일 때 late를 사용해서 초기화를 뒤로 미룰 수 있다.

     

    예제를 살펴보자.

     

     

     

    주의할 점은 late로 초기화를 뒤로 미룬 후에 해당 변수를 사용하기 전에 값을 대입하고 사용해야 한다.

     

     

     

     

    널인지 점검하는 '!' 연산자

     

    변수 이름 뒤에 '!' 연산자를 추가하면 이 변숫값이 널일 때 런타임 에러가 발생한다.

     

     

     

     

    멤버에 접근할 때 ?. , ?[] 연산자

     

    널 허용 객체나 리스트의 멤버에 접근할 때는 ?. 나 ?[] 연산자를 사용해야 한다.

     

    널 리스트에 인덱스로 접근할 때 null 반환하기

     

     

    널 객체의 멤버에 접근할 때 null 반환하기

     

     

     

    값을 대입할 때 ??= 연산자

     

    널 허용 변수에 널이 아닌 값만 대입하고 싶다면 ??= 연산자를 사용하면 된다.

     

     

     

     

    값을 대체할 때 ?? 연산자

     

    널 허용 변수가 널일 때 대체할 값을 지정하고 싶다면 ?? 연산자를 사용하면 된다.