[Dart] final와 const는 뭐가 다를까 (ft. JS와 JAVA와의 비교)

 

 

 

Dart의 const와 final


Flutter를 시작하려면 Dart 언어를 알아야하는데, 기본적인 자료형 외에도 필수로 적할 키워드가 있다.

바로 const와 final인데 이 두 키워드는 불변성을 나타내고 있지만 사용목적은 다르다. Java나 JavaScript를 이미 해 본 사람이라면 이 키워드 자체는 익숙한데 또 그것과 다른 점도 있다.

 

✔️ final의 특징

런타임을 포함해 한 번만 할당 가능하다

final로 선언된 변수는 한 번만 값을 할당할 수 있다. 할당 시점은 런타임을 포함해 언제든 가능하지만 그 이후 다시 변경할 수 없다.

final name = 'Flutter'; 
name = 'Dart'; // Error: name is final and cannot be reassigned.

위는 선언 시 할당 한 후, 다시 값을 대입할 때 오류가 발생할 거다. 이는 Java에서 쓰는 final과도 같다.

final String name = "SpringBoot";
name = "JAVA"; // Error: cannot assign a value to final variable 'name'

다만 Java에서는 자료형까지 명시해줘야 한다.

 

✔️const의 특징

컴파일 시점에 고정된 상수를 갖는다.
final과의 차이점은 바로 이 시점에 있다. '실행 전에 이미 값이 결정' 되어야 하기에, 런타임에 값을 건드릴 수 없다.
const pi = 3.14;
pi = 3.14159; // Error: Cannot assign to a const variable.
당연히 위 코드도 final처럼 재 할당을 하려고하면 불변성에 어긋나 오류 발생할 예정이다.
Java에서는 이걸  static final로 컴파일 타임 상수로 표현한다.
static final double PI = 3.14;
PI = 3.14159; // Error: cannot assign a value to final variable 'PI'

 

✔️JS의 const

js의 const는 그럼 Dart의 const와 동일한가? 아님 final과 동일한가? 따지자면 final이다.

 

Dart의 const와 비교하자면 Dart는 무조건 '컴파일 타임 상수'이다. 하지만 JS에선 '런타임 상수'를 허용한다. 그러므로 같은 성질을 지닌 final과 유사하다고 볼 수 있다.

▪️ Dart의 final

void main() {
  final List<int> numbers = [1, 2, 3];

  // 변수 재할당 불가
  // numbers = [4, 5, 6]; // Error: A final variable can only be set once.

  // 리스트 내부 요소 변경 가능
  numbers[0] = 10;
  print(numbers); // [10, 2, 3]
}

 

final로 선언한 number가 있다. 이 number는 한 번 초기화 되었으니 새로운 값은 재 할당 할 수 없다.

하지만 참조하고 있는 객체의 내부 값은 변경이 가능하다. 이것이 object-level immutability다.

 

▪️ Javascript의 const

if (true){
    const numbers = [1, 2, 3];

    // 변수 재할당 불가
    // numbers = [4, 5, 6]; // TypeError: Assignment to constant variable.

    // 리스트 내부 요소 변경 가능
    numbers[0] = 10;
    console.log(numbers); // [10, 2, 3]
}

// console.log(message); // ReferenceError
JS의 입장에서도 거의 같다. numbers가 불변으로 할당되었으니 재할당은 불가하지만 참조중인 객체 내부 요소는 변경할 수 있다.
하지만, JS의 const는 block scope를 가지는 게 차이다. 즉, JS측에선 이 const를 블록 내에서만 사용 가능하기에 class 안의 필드로서는 사용할 수 없다. 반대로 Dart의 경우 클래스 필드에서 final을 쓸 수 있다.

 

 

 

 

정리


  Final const
값 고정 시점 런타임 컴파일 타임
재할당 가능 여부 불가능 불가능
사용 용도 값이 실행 중에 결정될 때 고정된 상수값을 사용해야 할 때
Java 유사 키워드 final static final
JavaScript 유사 키워드 const와 유사하지만, scope에서 다름 (생략)