관리 메뉴

나만을 위한 블로그

[Dart] final vs const 본문

Flutter

[Dart] final vs const

참깨빵위에참깨빵 2024. 7. 22. 18:21
728x90
반응형

dart를 사용하다 보면 final, const 키워드를 사용하는 순간이 온다.

공식문서와 다른 글들을 보면서 두 키워드에 대해 확인한다.

 

https://dart.dev/language/variables#final-and-const

 

Variables

Learn about variables in Dart.

dart.dev

변수를 바꾸지 않으려는 경우 var 대신 final 또는 const를 사용하거나 타입에 추가하라. final 변수는 한 번만 설정 가능하고 const는 컴파일 타임 상수다. 인스턴스 변수(=클래스 안에 선언한 변수)의 경우 final은 쓸 수 있지만 const는 쓸 수 없다
아래는 final 변수를 생성, 초기화하는 예시다. 이 때 final 변수의 값은 (다른 곳에서) 바꿀 수 없다
final name = 'Bob'; // 타입 어노테이션 없이 사용
final String nickname = 'Bobby';
컴파일 타임 상수로 만들려는 변수엔 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를 중복해서 쓰지 마라 문서를 참고하라. final 변수가 아닌 변수의 값을 바꿀 수 있으며, 이는 기존에 const 값이 있던 경우에도 마찬가지다
foo = [1, 2, 3]; // const [] 였음
const 변수의 값은 (다른 곳에서) 바꿀 수 없다. 타입 검사 및 캐스팅(is, as), 컬렉션 if, 스프레드 연산자(...와 ...?)를 써서 상수를 정의할 수 있다
const Object i = 3; // 여기서 i는 int 값을 가진 const 객체다
const list = [i as int]; // 타입 캐스팅
const map = {if (i is int) i: 'int'}; // is와 컬렉션 if를 사용
const set = {if (list is List<int>) ...list}; // ...과 스프레드
final 객체는 수정할 수 없지만 그 필드는 바꿀 수 있다. 이와 비교해서 const 객체와 그 필드는 바꿀 수 없는 불변 객체다

 

내용을 정리하면 아래와 같다.

 

특징 final const
사용 예시 final name = "bob"; const bar = 100;
값이 결정되는 시점 런타임 컴파일 타임
객체의 필드 수정 가능 여부 가능 불가능
인스턴스 변수로 사용 가능한가? 가능 불가능
초기화 표현식에서 키워드 생략 가능 여부 불가능 가능
변경 가능성 변수 값 변경 불가능
객체의 필드 변경 가능
변수, 값, 객체의 필드 변경 모두 불가능
-> 불변성 보장
클래스 레벨에서 어떻게 사용할 수 있는가? 해당 없음 static const
타입 체크, 캐스팅, 컬렉션 if, 스프레드 연산자 사용 가능 여부 가능

 

다른 글들에선 어떻게 설명하는지 확인한다.

 

https://stackoverflow.com/questions/50431055/what-is-the-difference-between-the-const-and-final-keywords-in-dart

 

What is the difference between the "const" and "final" keywords in Dart?

What is the difference between the const and final keywords in Dart?

stackoverflow.com

final은 단일 할당을 의미한다. final 변수 또는 이니셜라이저가 있어야 한다. 값이 할당되면 final 변수의 값은 바꿀 수 없다

const는 dart에서 좀 더 복잡하고 미묘한 의미를 갖는다. const는 값을 수정한다. const [1, 2, 3] 같이 컬렉션을 만들 때 사용할 수 있고 const Point(2, 3)과 같이 객체를 만들 때 사용할 수 있다. 여기서 const는 객체의 전체 심층 상태를 컴파일 시점에 완전 결정할 수 있으며, 객체가 동결되어 완전히 변경되지 않음을 의미한다
const 객체는 컴파일 타임에 계산할 수 있는 데이터로 만들어야 한다. 생성자 객체에는 런타임에 계산해야 하는 무언가에 대한 접근 권한이 없다. 1+2는 유효한 상수 표현식이지만 새 Datetime.now()는 그렇지 않다...(중략)

그래서 뭘 의미하는가?

const
- 값이 런타임에 계산되는 경우엔 여기에 const를 쓸 수 없다
- 값이 컴파일 시점에 알려지는 경우(const a = 1;)엔 final 보다 const를 써야 한다
- 클래스 안에서 const를 쓰는 경우 static const로 선언해야 한다
- const 컬렉션이 있다면 그 안의 모든 게 const에 포함된다. final 컬렉션이 있다면 그 안의 모든 것은 final 컬렉션이 아니다

final
- 컴파일 시 값을 모르는 경우 const보다 final을 써야 한다
- 런타임에 계산되고 알려진다
- 변경할 수 없는 HTTP 응답을 원하거나 DB에서 뭔가를 조회할 때, 로컬 파일을 읽으려는 경우 final을 써라
- 컴파일 시점에 모르는 모든 것은 const 대신 final을 써야 한다

즉, const와 final 모두 재할당할 수 없지만 final 객체의 필드는 생성자나 final 그 자체가 아니라면 (생성자와 달리) 재할당할 수 있다

 

https://stackoverflow.com/a/53271272

 

What's with the final/const craze in Flutter?

Java have final as well as Dart, but as far as I have seen, most Java people avoid using it all the time, since it can make your code less readable. For example, final is used all the time in class

stackoverflow.com

const는 컴파일 타임에 값을 알 수 있고 앱의 전체 기간 동안 변수가 일정하다는 걸 의미한다. 컴파일 타임에 값을 알 수 있으므로 필요한 최적화를 수행할 수 있다. final은 값이 설정된 순간부터 일정하거나 불변임을 의미하지만 런타임에 설정된다. 따라서 컴파일 타임에는 알 수 없고 최적화할 수 없다. final을 쓰지 않으면 플러터에서 준수해야 하는 불변성을 잃게 된다. 위젯은 항상 수정하지 말고 생성해야 한다. 이를 적용하는 방법은 모든 필드를 final 필드로 만드는 것이다

 

이외에 다른 글들을 확인해도 위 2가지 스택오버플로우와 별다른 내용은 없다. 두 키워드의 특징을 잘 알고 사용하자.

반응형
Comments