const와 final은 둘 다 Dart에서 변경할 수 없는 변수를 선언할 때 사용되지만
사용 용도와 동작 방식에서 차이가 있습니다.
컴파일 타임과 런타임은 프로그래밍에서 코드가 실행되는 두 가지 주요 단계입니다. 이 두 개념은 코드가 언제 검증되고, 언제 실제로 실행되는지를 정의합니다.
들어가기 앞서 중요한 개념을 짚고 넘어가야 합니다.
저급(저수준) 프로그래밍 언어 (Low-Level Programing Language)
컴퓨터가 이해하기 쉽게 작성된 프로그래밍 언어로 컴퓨터 위주의 코드입니다.
수준이 낮다가 다른 뜻이 아닌, 더 하드웨어에 근간을 두고 있다는 뜻입니다.
실행속도가 매우 빠르지만 배우기가 어려우며 유지보수가 힘든 것이 단점입니다.
일반적으로 기계어와 어셈블리어를 말합니다.
기계어 (Machine Language)
기계어는 컴퓨터의 CPU가 직접 이해하고 실행할 수 있는 저수준의 언어로, 0과 1로 이루어진 이진수(binary digit)로 표현됩니다.
CPU의 레지스터, 메모리 주소, 명령어 등을 직접 다루기 때문에 매우 구체적이기 때문에
주로 하드웨어 코드를 빌드한다거나 하드웨어에 밀접하게 연관되어 있습니다.
하지만 0과 1로 사람이 읽고 쓰기엔 매우 어렵기 때문에 이를 보다 이해하기 쉬운 형태로 표현한 것이 어셈블리어입니다.
어셈블리어 (Assembly Language)
어셈블리어는 기계어 명령어에 대해 사람이 읽기 쉬운 기호를 사용합니다.
기계어와 다른 점은 알파벳도 추가로 사용할 수 있게 되어 좀 더 사람 친화적이긴 하지만 여전히 low-level의 언어입니다.
기계어와 1:1 대응이 되기 때문에 어셈블러(assembler)라는 번역 프로그램이 기계어로 변환합니다.
컴파일러 (Compiler)
고급 프로그래밍 언어를 실행 프로그램으로 만들기 위해 저급 프로그래밍 언어로 바꾸는 데 사용되는 프로그램입니다.
여기서 고급 언어란 인간 친화적 언어(C, C++, C#, JAVA, Python, Dart 등)를 말합니다.
어셈블러와 비슷한 개념이며
- 컴파일러 = 고급언어 ➡️ 어셈블리어 번역기
- 어셈블러 = 어셈블리어 ➡️ 기계어 번역기
라고 생각하면 됩니다.
또한
- 소스코드(원시코드)
- 고급언어로 작성된 코드 파일 (컴파일 이전)
- 목적코드
- 기계어로 작성된 코드파일 (컴파일 이후)
컴파일과정을 거쳐 출력된 코드를 목적 코드라고 부릅니다.
소스코드(원시코드)에서 목적 코드로 옮기는 과정을 컴파일이라고 합니다.
이 단계에서 컴파일러는 소스코드를 기계어 또는 중간 코드로 변환합니다.
결국
컴파일이란?
소스코드(Source Code) → 컴파일러에 의한 컴파일 → 목적코드(Object Code)
로 이해하시면 됩니다.
고급 언어의 실행 파일 변환까지 컴파일 과정
- 고급 언어 (High-level Programing Language)
• 인간 친화적 언어(C, C++, C#, JAVA, Python, Dart 등)로 소스 코드작성. - 소스 코드 (Source Code)
• 고급 언어로 작성된 코드 파일. - 컴파일러 (Compiler)
• 소스 코드를 어셈블리어로 변환하는 번역기를 거쳐 어셈블리어로 변환. - 어셈블리어 (Assembly Language)
• 저급 언어. - 어셈블러 (Assembler)
• 어셈블리어를 목적 코드로 변환하는 번역기를 거쳐 목적 코드 생성. - 목적 코드 (Object Code)
• 기계어 명령어와 데이터가 포함된 이진수(Binary) 파일. - 링커 (Linker)
• 여러 목적 코드 파일들과 라이브러리를 결합하고 외부 심볼들을 결합하고 재배치 작업을 통해 최종 실행 파일(.exe)을 만듦. - 기계어 / 실행파일 (Machine Code / ExeCutable)
• 최종 실행 파일(.exe)은 기계어 명령어로 구성되어 있으며 운영 체제에 의해 실행될 수 있음.
이 모든 개념을 짚고 넘어가야 컴파일 타임을 이해하기 쉽습니다.
컴파일 타임 (Compile Time)
컴파일 타임은 코드가 실행되기 전에 프로그램이 컴파일러에 의해 번역되는 단계입니다.
위 1번부터 8번까지의 과정을 컴파일 타임 이라고 합니다.
컴파일 타임에는 다음과 같은 일이 발생합니다.
- 구문 분석 (Syntax Checking)
- 코드의 문법이 올바른지 검사합니다. 문법 오류가 있으면 컴파일이 실패합니다.
- 타입 체크 (Type Checking)
- 변수와 표현식의 타입이 올바른지 확인합니다. 타입 불일치가 있으면 컴파일 오류가 발생합니다.
- 최적화 (Optimization)
- 컴파일러는 코드의 성능을 향상하기 위해 최적화를 수행할 수 있습니다.
- 코드 생성 (Code Generation)
- 소스 코드가 기계어 또는 중간 코드로 변환됩니다.
즉, 소스코드파일이 실행파일로 변환되는 과정을 컴파일 타임 이라고 합니다.
런타임 (Run Time)
컴파일된 실행 프로그램이 실제로 실행되는 단계입니다.
이 단계에서 프로그램은 메모리에 로드되고, CPU에서 실행됩니다.
사용자가 프로그램을 실행시킬 때 구동되는 시간을 말합니다.
런타임에는 다음과 같은 일이 발생합니다.
- 메모리 할당 (Memory Allocation)
- 프로그램이 실행될 때 변수와 객체에 메모리가 할당됩니다.
- 프로세스 제어 (Process Control)
- 프로그램의 흐름이 제어됩니다. 조건문, 반복문 등이 실행됩니다.
- 동적 작업 (Dynamic Operations)
- 파일 I/O, 네트워크 통신, 사용자 입력 등 동적 작업이 수행됩니다.
- 예외 처리 (Exception Handling)
- 런타임 오류가 발생하면 예외 처리기가 이를 처리합니다.
즉, 프로그램이 실제로 실행되는 단계이며 메모리 할당, 프로세스 제어, 예외 처리 등이 수행됩니다.
정리해 보자면 컴파일타임 → 런타임 순으로 실행됩니다.
const (Constant)
사전적 의미로는 '불변, 상수'라는 뜻을 가지고 있습니다.
컴파일 타임에 변수가 상수값을 정의하는 데 사용됩니다.
특징
- 변수를 설정할 때 한 번에 설정해줘야 합니다.
- 변수 값을 한 번만 설정할 수 있으며, 설정 후에는 변경할 수 없습니다.
- 컴파일 과정에서 값이 결정되므로 실행 속도가 빠릅니다.
- 메모리 할당 방식도 최적화되어 메모리 사용량을 줄일 수 있습니다.
- 주로 변하지 않는 값 (예: 원주율, 파일 경로)을 정의할 때 사용됩니다.
final
사전적 의미로는 '최종'이라는 뜻을 가지고 있습니다.
런타임에 상수값을 할당하고 변수를 한 번만 변경할 수 있으며 설정 후에는 변경할 수 없습니다.
특징
- 변수 값을 한 번만 변경할 수 있으며, 초기화된 후에는 다른 값으로 변경할 수 없습니다.
- 컴파일 타임이 아닌 런타임에 값이 결정되므로 const에 비해 실행 속도가 느릴 수 있습니다.
- 주로 초기화 후 값이 변경되지 않는 변수 (예: 화면 UI 요소, 데이터 객체)를 정의할 때 사용됩니다.
- 객체의 속성에 final을 사용할 수도 있습니다.
최종적으로 정리하면
- const
- 컴파일타임에 상수값을 설정
- final
- 런타임에 상수값을 설정
이라 볼 수 있습니다.
'Flutter > Dart Language' 카테고리의 다른 글
[플러터 flutter] 비동기 / 동기 async, awiat, future은 무엇인가? (0) | 2024.07.04 |
---|---|
[플러터 Flutter] 초기화란? (0) | 2024.06.29 |
[플러터 Flutter] Null-Safety와 late키워드 (0) | 2024.06.29 |
[플러터 Flutter] Private, getter/setter가 무엇인가? 어떻게 사용하는가? (0) | 2024.06.28 |
[플러터 Flutter] 인자(Parameter)와 인수(Argument)의 차이 (0) | 2024.06.27 |