본문 바로가기
Flutter for Beginners

Dart 3.0의 레코드 (Records)

by Andrew's Akashic Records 2025. 3. 4.
728x90

Dart

Dart 3.0의 레코드 (Records)

Dart 3.0에서 도입된 레코드(Records) 는 여러 개의 값을 하나의 그룹으로 묶어서 반환하거나 전달할 수 있는 튜플(Tuple) 형태의 데이터 구조입니다.

  • 기존 List나 Map 없이 여러 개의 값을 직접 반환할 수 있음
  • 클래스나 구조체를 만들지 않고도 여러 데이터를 그룹화 가능
  • 구조 분해(Destructuring) 를 통해 개별 변수에 쉽게 할당 가능
  • 가변 레코드와 불변 레코드 지원

1. 레코드 기본 사용법

1.1. 레코드 생성

void main() {
  var record = ('Alice', 30, true);

  print(record); // ('Alice', 30, true)
}
  • 여러 개의 값을 하나의 레코드로 묶어서 저장 가능

1.2. 레코드의 개별 값 접근

void main() {
  var record = ('Alice', 30, true);

  print(record.$1); // Alice
  print(record.$2); // 30
  print(record.$3); // true
}
  • 레코드의 요소는 $1, $2, $3 처럼 자동으로 생성된 필드명을 통해 접근 가능

1.3. 명명된 필드 레코드

void main() {
  var person = (name: 'Bob', age: 25, isStudent: false);

  print(person.name); // Bob
  print(person.age); // 25
  print(person.isStudent); // false
}
  • 명명된 필드를 사용하면 $1, $2 같은 기본 인덱스 대신, name, age, isStudent 같은 의미 있는 이름으로 접근 가능

2. 레코드를 활용한 함수 반환

레코드는 특히 여러 개의 값을 반환하는 함수에서 유용합니다.

2.1. 함수에서 레코드 반환

(String, int, bool) getUser() {
  return ('Charlie', 28, true);
}

void main() {
  var user = getUser();

  print(user.$1); // Charlie
  print(user.$2); // 28
  print(user.$3); // true
}
  • 여러 개의 값을 한 번에 반환 가능 (클래스 없이도 가능)

2.2. 명명된 필드를 사용한 함수 반환

({String name, int age, bool isStudent}) getUser() {
  return (name: 'Diana', age: 22, isStudent: true);
}

void main() {
  var user = getUser();

  print(user.name); // Diana
  print(user.age); // 22
  print(user.isStudent); // true
}
  • 필드명을 사용하여 접근하면 코드 가독성이 향상됨

3. 구조 분해 (Destructuring)

Dart 3.0에서는 레코드의 값을 쉽게 추출할 수 있도록 구조 분해 할당(Destructuring Assignment) 을 지원합니다.

3.1. 위치 기반 구조 분해

void main() {
  var (name, age, isStudent) = ('Eve', 21, false);

  print(name); // Eve
  print(age); // 21
  print(isStudent); // false
}
  • 레코드의 각 요소를 개별 변수에 할당 가능

3.2. 명명된 필드 구조 분해

void main() {
  var (name: userName, age: userAge) = (name: 'Frank', age: 35);

  print(userName); // Frank
  print(userAge); // 35
}
  • 필드명을 사용하여 특정 값을 쉽게 추출 가능

4. 레코드의 불변성과 복사

4.1. 레코드는 기본적으로 불변 (Immutable)

void main() {
  var user = ('Grace', 29);

  // user.$1 = 'Hannah'; // 오류 발생 (레코드 값 변경 불가)
}
  • 레코드는 기본적으로 불변이므로, 값을 변경할 수 없음

4.2. 레코드 복사 및 변경

레코드를 변경하려면 새로운 레코드를 생성해야 함.

void main() {
  var oldUser = (name: 'Isaac', age: 40);
  var newUser = (name: 'Isaac', age: 41); // 새로운 레코드 생성

  print(oldUser); // (name: Isaac, age: 40)
  print(newUser); // (name: Isaac, age: 41)
}
  • 레코드는 불변이므로 새로운 값을 가지는 레코드를 새로 만들어야 함

5. 레코드 비교

5.1. 동일한 값이면 같은 레코드로 인식

void main() {
  var record1 = ('John', 32);
  var record2 = ('John', 32);

  print(record1 == record2); // true
}
  • 레코드는 값이 동일하면 같은 것으로 판단됨

5.2. 필드 순서가 다르면 다른 레코드로 인식

void main() {
  var record1 = ('John', 32);
  var record2 = (32, 'John');

  print(record1 == record2); // false
}
  • 같은 값이어도 필드의 순서가 다르면 다른 레코드로 판단됨

5.3. 명명된 필드도 순서가 달라도 값이 같으면 동일한 레코드로 인식

void main() {
  var record1 = (name: 'John', age: 32);
  var record2 = (age: 32, name: 'John');

  print(record1 == record2); // true (필드 순서 상관 없음)
}
  • 명명된 필드는 순서가 달라도 같은 값이면 동일한 레코드로 판단됨

6. 레코드와 리스트, 맵 비교

특징 레코드 리스트
데이터 구조 정해진 필드 수 가변적 크기 키-값 쌍
불변성 기본적으로 불변 변경 가능 (List 사용) 변경 가능
데이터 접근 $1, $2, name 등 list[index] map[key]
데이터 비교 값이 같으면 같음 참조 비교 (== 다를 수도 있음) 참조 비교
  • 레코드는 클래스 없이도 여러 개의 값을 한 번에 다룰 수 있으며, 가독성과 타입 안정성을 높여줌

요약

기능 사용 예시
레코드 생성 var user = ('Alice', 30, true);
개별 값 접근 user.$1, user.$2
명명된 필드 사용 var person = (name: 'Bob', age: 25);
구조 분해 var (name, age) = user;
함수 반환 값으로 사용 (String, int) getUser() { return ('Charlie', 28); }
레코드 비교 record1 == record2
  • 레코드는 Dart 3.0에서 추가된 새로운 데이터 구조로, 여러 값을 한 번에 다룰 수 있음
  • 클래스를 만들지 않아도 여러 개의 값을 그룹화 가능
  • 구조 분해(Destructuring)를 통해 개별 변수에 쉽게 할당 가능
  • 불변(Immutable)이며, 값이 같으면 같은 레코드로 간주
  • 리스트, 맵보다 직관적인 데이터 구조 제공
728x90