본문 바로가기
프로그래밍/Flutter-Dart

[Flutter] record type

by 채연2 2024. 1. 25.

 

 

record

최소 3.0 버전 이상이 사용할 수 있는 record type에 대해 알아보려고 한다.

나는 회사 프로젝트 때문에 dart 2.19.6 버전을 사용중이라.. 대신 dartpad를 이용해서 사용해보았다.

 

record syntex

record는 소괄호로 묶인 named 필드 또는 positional 필드의 쉼표로 구분된 목록이다.

var record = ('first', a: 2, b: true, 'last');

 

 

record type annotation은 괄호 안에 쉼표로 구분된 type list이다. 이를 사용해서 반환 타입과 매개변수 타입을 정의할 수 있다.

(int, int) swap((int, int) record) {
  var (a, b) = record;
  return (b, a);
}

위 함수는 아래처럼 사용할 수 있다.

void main() {  
  var record = (3, 100);
  print(record);				//(3,100)
  
  print(swap(record));			//(100,3)
}

 

 

positional 필드는 괄호 안에 직접 들어가고, named 필드는 타입 및 이름 쌍의 중괄호로 구분된 섹션 내부에 들어간다.

또, named 필드는 각 필드 값 앞에 콜론(:)이 붙는다.

//positional field
(String, int) record;
record = ('A string', 123);

//named field
({int a, bool b}) record;
record = (a: 123, b: true);

 

 

타입은 같지만 이름이 다른 아래 두 named 필드는 record type이 다르다.

({int a, int b}) recordAB = (a: 1, b: 2);
({int x, int y}) recordXY = (x: 3, y: 4);

// Compile error!
// recordAB = recordXY;

 

 

타입은 같지만 이름이 다른 아래 두 positional 필드는 record type에 영향을 주지 않는다.

(int a, int b) recordAB = (1, 2);
(int x, int y) recordXY = (3, 4);

recordAB = recordXY; // OK.

 

 

record fields

record fields는 내장된 getter를 통해 접근 가능하다. record는 변경할 수 없으므로 field에는 setter가 없다.

named 필드는 동일한 이름의 getter를 노출하고, positional 필드는 $<position>을 사용하여 출력한다.

var record = ('first', a: 2, b: true, 'last');

print(record.$1); 			// Prints 'first'
print(record.a); 			// Prints 2
print(record.b); 			// Prints true
print(record.$2); 			// Prints 'last'

 

 

record types

record는 필드 타입에 따라 구조적으로 타입이 지정된다.

record의 각 필드에는 고유한 타입이 있다. 필드 타입은 동일한 record 내에서 다를 수 있고, type system은 record에서 액세스할 때마다 각 필드의 타입을 인식한다.

(num, Object) pair = (42, 'a');

var first = pair.$1; 
var second = pair.$2;

print(first.runtimeType);	// static type : 'num', runtime type : 'int'
print(second.runtimeType);	// static type : 'Object', runtime type : 'String'

 

 

Record equality

두 record의 모양(필드 집합)이 동일하고, 해당 필드의 값이 동일한 경우 두 record는 동일하다.

named 필드 순서는 record 모양의 일부가 아니므로 named 필드 순서는 동등성에 영향을 주지 않는다.

//positional field
(int x, int y, int z) point = (1, 2, 3);
(int r, int g, int b) color = (1, 2, 3);

print(point == color); // Prints 'true'.

//named field
({int x, int y, int z}) point = (x: 1, y: 2, z: 3);
({int r, int g, int b}) color = (r: 1, g: 2, b: 3);

print(point == color); // Prints 'false'

 

 

Multiple returns

record를 사용하면 함수가 함께 묶여있는 여러 값을 리턴할 수 있다. 리턴에서 record 값을 검색하려면 pattern matching을 사용하여 값을 local 변수로 분해한다.

final json = <String, dynamic>{
  'name': 'Dash',
  'age': 10,
  'color': 'blue',
};

void main() {  
  var (name, age) = userInfo(json);
  print((name, age));
}

(String, int) userInfo(Map<String, dynamic> json) {
  return (json['name'] as String, json['age'] as int);
}

 

 

 

 

 

320x100

댓글