final
과 const
에 대해서 알아보자.
final
과 const
는 상수(constant)이며 항상 같은 수, 변하지 않는 수를 말한다.
즉, 한 번 선언하면 값을 바꿀 수 없다.(재할당이 불가능)
final
과 const
를 이해하기전
컴파일-타임(Compile-Time) 과 런타임(Runtime) 을 알아야한다.
개발자가 소스코드를 작성하고 컴파일이라는 과정을 통해 기계어코드로 변환 하여 실행 가능한 프로그램이 된다. 이러한 과정을 컴파일-타임(Compile-Time) 이라고 부른다.
컴파일과정을 마친 프로그램은 사용자에 의해 실행되며 동작되어지는 상태를 런타임(Runtime)이라고 한다.
final
은 동적으로 메모리에 할당이라고 말해준다.
즉, 컴파일-타임 에는 변수할당을 하지 않고 런타임 시에 변수할당을 한다.
덕분에 컴파일-타임 에서는 확인할 수 없는 값들을 동적으로 변수에 할당할 수 있게 된다.
컴파일-타임 에서 확인할 수 없는값(런타임 시 확인가능한것)으로는 DateTime.now()
가 있다.
컴파일-타임 에 변수선언이 이루어진다.
덕분에 컴파일러는 모든 const
객체에 대해 동일한 메모리 부분을 할당하여 객체를 불변으로 만든다.
쉽게말해 앱을 실행할 때 한 번만 생성한다는 것이고, 이는 리소스 낭비를 하지 않는 다는 것이다.
✨ 추가설명
Class
안에서 const
키워드는 static
필드에서만 사용 가능하다.Class
가 인스턴스화 되기 전, compile-time에 해당 필드의 값이 정해지기 때문이다.(static
필드는 compile-time
에 메모리 상에 올라단다.)static
은 쉽게말해 instance
를 만들지 않고 언제든 실핼할 수 있는 키워드, 이 키워드를 사용하지 않으면 인스턴스를 만들어서 참조해야한다.clas ApiService {
static const String baseUrl = "https://api링크";
static const String today = "today";
static Future<String> getTodaysPic() async {
//api date get
}
}
시간은 컴파일시 구해지는게 아닌 런타임중인 현재 시간을 알아야 하는 기능으로 DateTime.now()
는 final이 아닌 const로 선언하면 에러가 발생한다.
void main(){
final nowTime = DateTime.now();
}
void main(){
const nowTime = DateTime.now();
// Error: Cannot invoke a non-'const' constructor where a // const expression is expected.
// Try using a constructor or factory that is 'const'.
}
API 통신하여 비동기 방식가져오는 Future 를 사용할때의 예제
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
// 2. 빨간줄(error표시)이 난다 왜일까?
// 아래 Future<String> text는 컴파일 전에 알 수 있는게 아니다.
// Future를 포함한 HomeScreen을 컴파일 시
// 메모리 할당을 하려고 하기 때문에 에러가 난다.
// 그러기에 const를 지워줘야 한다.
Future<String> text = ApiService.getText();
// 1. Future는 컴파일시가 아닌 런타임 시에 값을 알 수 있다.
Widget build(BuildContext context) {
return 화면UI;
}
}
클래스 안에 Future
를 넣었다 그러면 클래스가 const
일 수가 없다.
Future
를 기다려 줘야 하는데 이는 컴파일-타임을 넘어서 런타임에 알 수 있기 때문.
이해의 가장 중요한 포인트는 런타임과 컴파일-타임의 차이이다.
reference