Flutter를 공부하며 Dart가 C++와 유사한 문법을 가지고 있어서 쉽다고 느꼈습니다.
하지만 다소 차이가 있기 때문에, 빠르게 Dart의 개념을 잡고 가면 더 빨리 실력이 늘 것이라는 생각이 들었습니다.
그래서 Dart의 공식 문서를 위주로 공부하며 C++의 기본적인 지식을 바탕으로 글을 써보려고 합니다.
변수
Dart의 변수에 대해 학습합니다.
dart-ko.dev
타입 추론
타입 안정성이 높은 Dart 코드일지라도, var를 사용하여 명시적으로 타입을 지정하지 않고 변수를 선언할 수 있습니다.
타입 추론 덕분에 이런 변수들의 타입은 초기 값을 통해 결정됩니다.
var name = 'Voyager I';
var year = 1977;
var antennaDiameter = 3.7;
var flybyObjects = ['Jupiter', 'Saturn', 'Uranus', 'Neptune'];
var image = {
'tags': ['saturn'],
'url': '//path/to/saturn.jpg'
};
var 키워드는 C++의 auto를 생각하시면 됩니다.
Dart 컴파일러가 해당 값의 타입을 분석하여 변수의 타입을 결정합니다.
만약 객체가 단일 타입으로 제한되지 않는다면, Object 타입으로 명시합니다. (필요하다면 dynamic 사용)
Object name = 'Bob';
디폴트 값
Nullable 타입을 가지는 초기화되지 않은 변수는 초기 값으로 null을 가질 수 있습니다.
Dart의 다른 모든 것과 마찬가지로 숫자도 객체이기 때문에 숫자 타입의 변수도 처음에는 null입니다.
int? lineCount;
assert(lineCount == null);
여기서 ?는 Null-safty와 관련된 개념인데 Null-safty에 대한 내용이 생각보다 방대하기 때문에, 추후에 설명하도록 하겠습니다.
null safty를 활성화했다면, non-nullable 변수를 사용하기 전에 값들을 초기화해야만 합니다.
지역 변수를 선언과 동시에 초기화할 필요는 없지만, 사용하기 전에 값을 할당해야 합니다.
예를 들어, 다음 코드는 lineCount가 print()로 전달될 때까지 null이 아님을 알 수 없기 때문에 유효합니다.
int lineCount;
if (weLikeToCount) {
lineCount = countLines();
} else {
lineCount = 0;
}
print(lineCount);
Late 변수
‘late’ 키워드는 대표적으로 2가지 상황에 사용됩니다.
- 선언 이후에 초기화되는 non-nullable 변수를 선언하는 것
- 변수의 초기화를 지연하는 것 (지연 초기화: Lazy initialization)
앞서 Null-safty에 대해서 언급하였습니다.
null-safty에 대해 간단히 소개하면, Dart에서 기본적으로 변수를 선언할 때 null을 허용하지 않는 것을 말합니다.
late 변수를 사용하면 변수 선언 시 null을 허용하지 않으면서도 나중에 초기화할 수 있습니다.
late String description;
void main() {
description = 'Feijoada!';
print(description);
}
💡 late 변수의 초기화를 실패하였다면, 해당 변수를 사용할 때 런타임 에러가 발생합니다.
// 이 프로그램에서 readThermometer()에 대한 유일한 호출입니다.
late String temperature = readThermometer(); // 지연 초기화.
만약 위의 예제에서의 temperature이라는 변수가 사용되지 않는다면, readThermometer() 함수는 호출되지 않습니다.
Final, Const
변수를 변경할 생각이 없다면, var 대신 final이나 const를 사용하거나 , 지정한 타입에 추가하여 사용합니다.
final 변수는 오직 한 번만 설정될 수 있습니다. const 변수는 컴파일 타임 상수입니다. (const 변수는 내부적으로 final)
-> 공식 문서에는 이렇게 적혀 있었는데 어떤 뜻인지 바로 이해하긴 어려웠습니다.
쉽게 설명하자면 final 변수는 런타임에 값이 결정되고, 변수 선언 후 한 번만 초기화되는 변수입니다.
그리고 const 변수는 컴파일 타임에 값이 결정되어야 하므로, 변수 선언과 동시에 값이 초기화되어야 합니다.
즉, 런타임에 결정되어야 하는 값, 예를 들어 사용자 입력, 시간 정보, 네트워크 요청 결과 등에는 final을 사용합니다.
다음은 final 변수를 생성, 설정하는 예제입니다.
final name = 'Bob'; // 타입 어노테이션이 없음
final String nickname = 'Bobby';
final 변수의 값은 변경할 수 없기 때문에, 변경을 시도할 경우 에러가 발생합니다.
name = 'Alice'; // 에러: final 변수는 한 번만 설정될 수 있습니다.
컴파일 타임 상수인 변수를 생성할 때 const를 사용합니다.
const 변수가 클래스 레벨의 변수라면, static const로 표시합니다.
변수를 선언할 때, 숫자, 문자열 리터럴, 상수 변수, 또는 상수 숫자에 대한 산술 연산의 결과 같은 값들은 컴파일 타임 상수로 선언합니다.
const bar = 1000000; // 압력의 단위 (dynes/cm2)
const double atm = 1.01325 * bar; // 표준 대기
const 키워드는 상수 변수를 선언할 때만 쓰이는 것이 아닙니다.
상수 값을 만드는 데 사용할 수 있을 뿐 아니라, 상수 값을 만드는 생성자를 선언할 수도 있습니다. 모든 변수는 상수 값을 가질 수 있습니다.
var foo = const [];
final bar = const [];
const baz = []; // `const []`와 동일
위의 baz처럼, const 선언의 초기화 식에 const를 생략해도 됩니다.
이전에 const 값을 가지고 있었더라도, non-final, non-const 변수의 값을 변경할 수 있습니다.
foo = [1, 2, 3]; // const [] 였음
→ foo 변수의 값이 const값이었어도. foo 변수 자체가 상수 변수가 아니므로 변경할 수 있습니다.
이렇게 Dart의 변수에 대해서 알아보았습니다.
null-safty 개념을 제외하면 거의 C++와 유사하다고 느껴집니다.
그럼 다음에는 Null-Safty의 개념에 대해 다뤄보겠습니다.
긴 글 읽어주셔서 감사합니다.
'개발 > Flutter' 카테고리의 다른 글
[Flutter] flutter_dotenv 패키지로 환경변수 설정(feat relase 환경에서의 오류 해결) (1) | 2024.09.26 |
---|---|
[Flutter] 채팅앱 만들기(1) 기존 앱 분석 (main) (0) | 2024.08.28 |
[Flutter] 채팅앱 만들기 - Flutter앱을 Firebase와 연동하기 (0) | 2024.08.17 |