변수
A tour of the Dart language 페이지를 공부하면서 정리한 내용입니다.
변수는 아래와 같이 선언하고 초기화 합니다.
변수에는 객체의 참조를 저장합니다. 변수 name
은 "Bob"을 값으로 갖는 String
객체를 참조합니다. 컴파일러에 의해 name
은 String
타입으로 추론됩니다. 변수가 특정 타입으로 제한되지 않을 경우 Object
또는 dynamic
을 사용할 수 있습니다.
변수 선언 시 명시적으로 타입을 지정할 수도 있습니다.
기본값
Nullable 타입의 기본값(Default value)은 null
입니다. 숫자를 포함 Dart의 모든 것은 객체이므로 nullable 정수 타입도 초기값은 null
을 갖습니다.
프로덕션 모드에서 assert() 호출은 무시됩니다. 개발 모드에서는 assert(condition)
의 condition
이 false
이면 예외를 던집니다. 보다 자세한 내용은 여기를 참고해주세요.
Null safety를 사용할 때 non-nullable 변수는 반드시 초기화 후에 사용해야 합니다.
지역 변수는 선언 지점에 초기화할 필요는 없지만, 반드시 초기화 후에 사용해야 합니다. 예를 들어, 아래 예제에서 컴파일러는 lineCount
가 print()
함수에 전달될 때 반드시 초기화된다는 사실을 알 수 있어서 정상적으로 컴파일 및 실행이 됩니다.
최상위 변수와 클래스 변수는 게으른 초기화(Lazily initialized)를 합니다. 해당 변수들은 최초로 사용되는 시점에 초기화 됩니다.
late 변수
Dart 2.12 버전에서 late
제어자(Modifier)가 추가되었으며, 아래 두 가지 경우에 사용합니다.
Non-nullable 변수를 선언만 하고 초기화하지 않는 경우
변수가 게으른 초기화를 하는 경우
Dart 컴파일러의 제어 흐름 분석은 non-nullable 변수가 사용되기 전에 null
이 아님을 알 수 있습니다. 하지만 최상위 변수와 인스턴스 변수의 경우 분석이 실패할 수 있습니다. 위 예제에서도 lineCount
가 초기화되기 전에 print()
에 전달했는데, 이 경우 컴파일 에러가 발생합니다.
변수가 사용되기 전에 반드시 초기화 된다는 사실을 알고 있다면, late
제어자를 이용해 Dart 컴파일러에게 사실을 알릴 수 있습니다.
late
제어자를 추가한 변가 초기화에 실패했다면 변수 사용 시 런타임 에가 발생하므로 주의가 필요합니다.
late
제어자를 이용해 변수를 선언하면서 동시에 초기화하면 변수를 처음 사용하는 시점에 게으른 초기화를 수행합니다. 게으른 초기화는 몇 가지 경우 유용하게 사용할 수 있습니다.
변수가 실제로 사용되지 않을 수 있는 경우
변수 초기화 비용이 비싼 경우
인스턴스 변수의 초기화를 진행 중인 상태에서 해당 인스턴스의 초기화 프로그램이
this
에 접근이 필요한 경우
아래 예제에서 temperature
변수는 사용되지 않기 때문에 변수 초기화를 위해서 값비싼 _readThermometer()
함수는 호출되지 않습니다.
final과 const
변수를 변경하고 싶지 않다면 var
대신 final
또는 const
를 사용해주세요. final
변수는 한번만 할당할 수 있도록 합니다. const
변수는 컴파일 타임 상수(Compile-time constant)입니다. const
변수는 값을 변경할 수 없고, 암묵적으로 final
이기 때문에 재할당하는 것도 불가능합니다.
인턴스 변수는 final
변수일 수 있지만 const
변수일 수 없습니다.
final
변수는 아래와 같이 선언하고 초기화 합니다. final
변수를 재할당 하려고 시도하면 컴파일 에러가 발생합니다. final
변수는 재할당할 수 없지만, 객체의 속성을 변경할 수는 있습니다.
컴일 타임 상수로 만들고 싶다면 const
를 사용합니다. const
변수가 클래스 수준에 존재한다면, static const
로 표현합니다. 숫자나 문자열 리터럴, 상수간의 연산 결과 등은 컴파일 타임 상수로 설정할 수 있습니다. const
변수는 객체의 속성도 변경할 수 없습니다.
const
키워드는 상수 변수를 선언하는 것 외에 상수 값을 생성하거나, 상수 값을 생성하는 생성자를 선언할 수도 있습니다. 클래스 인스턴스 생성 시 const
로 선언하면 해당 객체는 컴파일러에 의해서 최적화 됩니다. 컴파일러는 객체를 불변(Immutable)하게 만들고, 동일한 객체 생성에 대해서 같은 메모리를 가르키게 합니다.
타입 검사(Type checks), 타입 케스트(Type Casts), 컬렉션 if
, 전개 연산자(Spread operators) ..., ...?
를 사용해 상수를 정의할 수 있습니다.
Last updated