본문 바로가기
프로그래밍 언어/Dart

Dart 변수 심화 가이드 – late, final, const, 와일드카드 변수 활용하기

by 희품 2026. 1. 3.
반응형

Dart 변수의 기본적인 활용 방법을 알았다면, 조금 더 심화된 사용법을 알아볼 차례이다.
late, final, const 키워드를 중심으로, 와일드카드 변수(_)와 다양한 문맥에서 사용되는 변수를 알아보자.

 

late Variable(지연 변수), 나중에 초기화하는 변수

Dart에서는 non-nullable 변수, null을 허용하는 변수를 선언할 때 바로 초기화해야 한다.

하지만 가끔 초기화를 지연해야 할 때가 있다. 이럴 때 late 키워드를 사용한다.

late String description;

void main() {
  //print(description); // 초기화 하기 전에 사용하려고 하면 컴파일 오류 발생!
  description = 'Dart is powerful!';
  print(description);
}
  • late를 붙이면 선언만 하고 나중에 값을 할당할 수 있다.
  • 단, 값을 읽기 전에 반드시 초기화해야 하며, 그렇지 않으면 런타임 오류가 발생한다.

 

 

고정된 값, 상수를 위한 키워드, final과 const

변수를 절대로 변경할 일이 없는 경우도 있다. 예를 들면, 파이(π)의 값을 3.14라고 한다면, 매 번 3.14를 넣는 것보다, 3.14라는 값을 가진 변수를 사용하면 코드를 보기도 쉽고, 관리하기도 효율적이다.

이렇게 고정된 값을 변수로 사용하고 싶을 때는, var를 사용하기보다 final이나 const를 사용한다.

final String name; 처럼 Type를 지정할 수도 있지만, 보통은 생략하고 final이나 const만 쓰는 경우가 많다.

final

  • 한 번만 값을 할당할 수 있다.
  • 런타임 시에 값이 결정된다.
final now = DateTime.now();

const

  • 컴파일 타임에 값을 고정해야 한다.
  • const 변수는 프로그램이 시작되기 전에 완전히 결정된 값이어야 한다.
const pi = 3.1415;

 

즉, final은 런타임에, const는 컴파일 타임에 고정된다.

 

final이나 const로 선언한 변수는 변수가 아니라 상수라고 볼 수 있다. 어려운 설명보다는 예시를 보면 쉽게 이해할 수 있을 것이다.

final String nickname = 'Bobby';
final name = 'Bob'; // 일반적으로 타입을 생략한다.
name = 'alice'; // 오류 ! final 값은 변경할 수 없음.

const bar = 1000000; // 압력 단위 (dynes/cm2)
const double atm = 1.01325 * bar; // 표준 대기압 예시. bar는 const이기 때문에 atm 정의에 사용할 수 있음.

var foo = const [];
final bar = const [];
const baz = []; // const [] 와 동일

foo = [1, 2, 3]; // 이전에는 const [], foo가 const가 아니기 때문에 변경 가능.

baz = [42]; // 오류! baz는 final 상수이기 때문에 변경 불가능

// 단순한 숫자나 문자열 외에도 다양한 형식의 const 선언 가능.
const Object i = 3;
const list = [i as int];
const map = {if (i is int) i: 'int'};
const set = {if (list is List<int>) ...list};

 

Class를 상수로 사용하기 위해서는 static const로 선언해야 된다는 규칙이 있으며, final 객체는 변경할 수 없지만, 그 필드는 변경할 수 있다. 반면, const 객체는 객체를 변경할 수도 없고, 필드 역시 변경이 불가능한 완전한 불변 객체이다.

 

이 내용은 Class의 특징과, 컴파일 타임 변환에 대한 복합적인 이해가 필요하기 때문에, 지금 이해하지 않고 넘어가도 좋다.

 

final과 const의 사용 용도, 런타임과 컴파일 타임 변환

한번 지정되면 변경이 안되는 상수 값인 final과 const를 왜 구분해서 쓰는 걸까? 특징을 비교해 보자.

  final const
값 결정 시점 실행 시점에 결정 컴파일 시점에 결정
수정 가능성 재할당 불가 (필드 수정 가능) 완전 불변 (필드도 수정 불가)
대표 사용 예시 API 응답, 사용자 입력 등 실행 중 결정되는 값 수학 상수, 고정 문자열, 상수 리스트 등
선언 위치 지역 변수, 최상위 변수, 클래스 인스턴스 변수 지역 변수, 최상위 변수, static const 클래스 변수
기타 특징 최초 1회 값 설정 가능 선언 즉시 메모리에 상수로 고정
  • final: 프로그램 실행 도중 결정되지만 변경할 필요가 없는 값에 사용한다.
  • const: 프로그램 실행 전부터 값이 명확히 정해져 있으며 절대 변하지 않아야 하는 값에 사용한다.

예를 들어, 서버로부터 받은 설정 값은 final로 선언하고, 원주율(π) 같은 수치는 const로 선언하는 것이 적절하다.

 

와일드카드 변수 _

와일드카드 변수 _는 언더 바(_)를 사용한다. Dart에서 이 값은 신경 쓰지 않아도 된다는 의미로 사용된다.

주로 함수, 반복문, 매개변수에서 필요 없는 값을 무시할 때 쓴다.

와일드카드 변수는 Dart 버전 3.7 이상에서부터 지원한다.
for (var _ in [1, 2, 3]) {
  print('반복 실행');
}
  • 리스트의 값을 굳이 사용할 필요가 없을 때 _를 쓴다.
  • 코드를 간결하게 만들고, 의도를 명확하게 표현할 수 있다.

와일드카드를 사용한 코드의 예시를 확인해 보자.

main() {
  //지역 변수 선언
  // 사실상 이렇게 사용하는 것은, 특수한 목적이 없는 이상 의미는 없다.
  var _ = 1;
  int _ = 2;
  
  // for 루프 선언
  // list를 순회할 때 사용한다.
  // 별다른 index 변수나 임시 변수를 선언할 필요 없이 간단히 list를 모두 조회할 수 있다.
  for (var _ in list) {}
  
  // catch 블록 매개변수
  // e 등 매개변수는 있지만, 굳이 필요가 없을 때 간편하게 사용할 수 있다.
  try {
  throw '!';
  } catch (_) {
  print('oops');
  
  // 제네릭 타입 및 함수 타입 매개변수
  // 템플릿을 간편하게 사용할 수 있다.
  // 템플릿, 제네릭 타입의 이해가 필요하기 때문에, 지금 꼭 알고 넘어갈 필요는 없다.
  class T<_> {}
  void genericFunction<_>() {}
  takeGenericCallback(<_>() => true);
  
  // 함수 매개변수
  // 함수에서도 다양하게 사용할 수 있다.
  // 제네릭 타입과 마찬가지로, 이런 방식으로 사용할 수 있다정도로 알고 넘어가도 된다.
  Foo(_, this._, super._, void _()) {}
  list.where((_) => true);
  void f(void g(int _, bool _)) {}
  typedef T = void Function(String _, String _);
}
  
}

Dart의 변수는 단순히 값을 저장하는 것을 넘어, 프로그램 흐름과 안전성을 좌우하는 중요한 요소다.

late, final, const, 그리고 와일드카드 _를 적절히 사용하면 코드의 품질과 가독성을 높일 수 있다.

다양한 문맥에서 변수가 어떻게 활용되는지 감을 잡아두면 앞으로의 Dart 프로그래밍이 훨씬 수월해질 것이다.

여러분의 의견이나 궁금증이 큰 도움이 됩니다. 댓글로 자유롭게 이야기해 주세요.

#Dart #Dart언어 #Dart변수 #late #final #const #와일드카드 #프로그래밍언어 #개발자 #Dart프로그래밍

반응형