Dart 튜토리얼 4편: 컬렉션 완전 정복

요약#

핵심 요지#

  • 문제 정의: 동적 언어에서는 컬렉션1에 잘못된 타입이 들어가도 실행 전까지 알 수 없다.
  • 핵심 주장: Dart는 리스트2·3·4이터러블5, 레코드6, 제네릭7으로 데이터 구조를 안전하게 표현한다.
  • 주요 근거: 컬렉션 리터럴, 순차 접근 규칙, 레코드의 고정 길이, 제네릭 타입 인자8를 제시한다.
  • 실무 기준: 타입 인자를 명시하면 잘못된 타입 추가를 도구가 컴파일 단계에서 감지한다.

문서가 설명하는 범위#

  • 컬렉션 리터럴과 기본 사용법을 다룬다.
  • Iterable의 정의와 순차 접근 규칙을 설명한다.
  • record 문법과 필드 접근 규칙을 소개한다.
  • genericstype argument의 역할을 정리한다.

읽는 시간: 14분 | 난이도: 초급


참고 자료#


문제 상황#

JavaScript와 Python 같은 동적 언어에서는 배열이나 리스트에 어떤 타입이든 넣을 수 있습니다.
실행해봐야만 잘못된 타입이 들어갔는지 알 수 있어서 디버깅이 어렵습니다.

기존 방식의 한계#

// JavaScript 예시
const numbers = [1, 2, 3];
numbers.push("hello"); // 타입 체크 없음
numbers.push(true); // 타입 체크 없음
// 나중에 사용할 때 오류 발생
const sum = numbers.reduce((a, b) => a + b); // NaN 출력

문제는 다음과 같습니다.

  • 컬렉션에 어떤 타입이든 넣을 수 있어서 일관성이 없다.
  • 실행 전까지 잘못된 타입을 발견할 수 없다.
  • 순차 접근 방식과 인덱스 접근 방식의 차이가 명확하지 않다.

해결 방법#

Dart는 컬렉션 타입을 제네릭으로 선언하고, Iterablerecord로 구조를 명확히 구분합니다.

단계 1: 컬렉션 리터럴과 제네릭 타입#

Why#

NOTE

컬렉션을 쓰기 시작하면 가장 먼저 부딪히는 문제는 “아무 값이나 들어가서, 나중에 깨지는 것”입니다.
그래서 컬렉션에 들어갈 값의 타입을 처음부터 고정하는 편이 안전합니다.

var numbers = <int>[1, 2, 3];
// numbers.add('hello'); // 컴파일 오류

What#

NOTE

genericsList/Set/Map 같은 타입에 타입 인자를 붙여 요소 타입을 고정하는 기능입니다.

How#

TIP

Dart는 List, Set, Map 리터럴을 기본으로 제공하며, genericstype argument로 요소 타입을 지정합니다.

var names = <String>['Seth', 'Kathy', 'Lars'];
var uniqueNames = <String>{'Seth', 'Kathy', 'Lars'};
var pages = <String, String>{
'index.html': 'Homepage',
'robots.txt': 'Hints for web robots',
};

타입 안전성 확보

var numbers = <int>[1, 2, 3];
// numbers.add('hello'); // 컴파일 오류: String을 int 리스트에 추가 불가
numbers.add(4); // OK

Watch out#

WARNING

타입을 고정했다면, “잠깐이라도 다른 타입을 끼워 넣기”는 허용되지 않습니다.
한 번 잘못 들어가면 나중에 어디서 깨지는지 찾기 어려워지기 때문입니다.

결론: 타입 인자를 지정하면 정적 분석이 잘못된 요소 타입을 컴파일 단계에서 오류로 보고합니다.


단계 2: Iterable의 순차 접근#

Why#

NOTE

List처럼 인덱스 접근을 계속 쓰다 보면, Iterable에서도 같은 방식이 될 거라고 착각하기 쉽습니다.
하지만 Iterable은 “순차 접근”을 핵심 규칙으로 둡니다.

Iterable<int> iterable = [1, 2, 3];
// iterable[1]; // 컴파일 오류

What#

NOTE

Iterable은 요소를 순서대로 꺼내는 인터페이스이며, 인덱스 연산([])이 기본 규칙이 아닙니다.

How#

TIP

Iterable은 요소를 순차적으로 접근하는 컬렉션 인터페이스입니다.
ListSetIterable이지만, Iterable 자체는 [] 연산자를 지원하지 않습니다.

Iterable<int> iterable = [1, 2, 3];
// iterable[1]; // 컴파일 오류: Iterable에는 [] 연산자 없음
int value = iterable.elementAt(1); // OK: elementAt() 메서드 사용

Watch out#

WARNING

인덱스가 꼭 필요하다면 List를 쓰는 편이 더 자연스럽습니다.
Iterable에 억지로 인덱스 접근을 붙이면, 코드의 의도가 흐려질 수 있습니다.

순차 접근 패턴

var iterable = [1, 2, 3];
// for-in 루프로 순차 접근
for (var element in iterable) {
print(element);
}
// iterator로 직접 제어
var iterator = iterable.iterator;
while (iterator.moveNext()) {
print(iterator.current);
}

결론: Iterable 전용 접근 메서드를 사용해 순차 접근 규칙을 지키고, 컴파일러가 잘못된 접근을 방지합니다.


단계 3: record로 구조적 데이터 표현#

Why#

NOTE

서로 다른 타입의 값 몇 개를 “한 번에 묶어서” 넘기고 싶을 때가 있습니다.
이때 매번 클래스를 만들지 않아도 되는 방식이 있으면, 코드가 빨라집니다.

// (이름, 나이)처럼 두 값을 같이 돌려주고 싶다.
(String, int) userInfo() => ('Alice', 25);

What#

NOTE

record는 여러 값을 한 번에 묶는 불변 구조이며, 위치 필드와 이름 있는 필드를 함께 가질 수 있습니다.

How#

TIP

recordimmutable9이며 fixed length10 구조입니다.
heterogeneous11 필드를 가질 수 있어서 서로 다른 타입을 함께 담을 수 있습니다.
Dart 버전 3.0 이상이 필요합니다.

var record = ('first', a: 2, b: true, 'last');
print(record.$1); // first (위치 필드)
print(record.a); // 2 (이름 있는 필드)
print(record.b); // true (이름 있는 필드)
print(record.$2); // last (위치 필드)

Watch out#

WARNING

위치 필드($1, $2)는 순서에 의존합니다.
필드가 늘어날 가능성이 있거나 의미가 중요한 값이라면, 이름 있는 필드(a, b처럼)를 쓰는 편이 더 안전합니다.

함수에서 여러 값 반환

(String, int) userInfo() {
return ('Alice', 25);
}
var info = userInfo();
print('Name: ${info.$1}, Age: ${info.$2}');

결론: 클래스 선언 없이 구조적 데이터를 표현하고 접근할 수 있습니다.
타입 안전성을 유지하면서 여러 값을 반환할 수 있습니다.


Footnotes#

  1. collection(컬렉션): 여러 값을 담는 데이터 구조다.

  2. List(리스트): 순서가 있는 컬렉션이다.

  3. Set(셋): 중복을 허용하지 않는 컬렉션이다.

  4. Map(맵): 키와 값의 쌍을 저장하는 컬렉션이다.

  5. Iterable(이터러블): 요소를 순서대로 접근할 수 있는 컬렉션 인터페이스다.

  6. record(레코드): 이름 없는 필드 묶음을 표현하는 불변 구조다.

  7. generics(제네릭): 타입을 매개변수로 받아 재사용 가능한 타입을 만드는 기능이다.

  8. type argument(타입 인자): 제네릭에 전달하는 구체적인 타입이다.

  9. immutable(불변): 값이 생성된 뒤 변경되지 않는 성질이다.

  10. fixed length(고정 길이): 필드 개수가 고정되어 있다는 뜻이다.

  11. heterogeneous(이종): 서로 다른 타입의 필드를 함께 가질 수 있다는 뜻이다.

공유

이 글이 도움이 되었다면 다른 사람과 공유해주세요!

Dart 튜토리얼 4편: 컬렉션 완전 정복
https://moodturnpost.net/posts/dart/dart-collections-guide/
작성자
Moodturn
게시일
2026-01-04
Moodturn

목차