//positional params만 있고 named params가 없는 record 선언
(int, String, bool) myRecord;
//initialize
myRecord = (0, "zero", true);
//positional과 named를 모두 가진 형태
(bool p, {int i, String n, bool b}) myRecord2 = (true, i: 0, n:"zero", b:true);
myRecord.$1
같이 record객체의 해당 순서에 있는 값을 가져다 쓸 수 있다.또한 중괄호 {} 를 넣어서 named 필드로 만들 수 있다.
named필드는 $ + 번호
를 쓰지않고 record 이름 뒤에 . + field name
으로 직접 불러올수 있다.
하지만 이 경우 순서를 쓸 수 없다.
그리고(int i, String a, bool b) myRecord;
같이 positional field에도 이름을 붙일 수 있는데, 이는 문서화를 위한 기능으로 외부에서 불러다 쓸 수는 없다. 그냥 $ + 번호
로 불러야 한다.
이 둘을 혼용해서 쓰는 경우 positional 까지는 번호로 불러내되, named 부터는 다시 이름붙인 key값으로 불러내야 한다.
추가적으로 필드의 이름은 언더스코어( _ ) 를 쓸 수 없다.
Records는 익명성, 불변성, 집계성을 가진 타입이며
다른 컬렉션 유형(List, Set, Map 등등)과 마찬가지로 여러 개체를 하나의 개체로 묶을 수 있다.
하지만 다른 컬렉션 유형과 달리 Record는 크기와 유형이 고정되어 있다.
Records는 실제 값이므로 변수에 저장하고, 중첩하고, 함수와 주고받을 수 있으며, 목록, 맵, 집합과 같은 데이터 구조에 저장할 수 있다.
Dart Pad에서 Record 타입에 대한 Documentation을 확인하면 아래와 같이 써있다.
Record라는 클래스가 추상클래스로 존재하지만 사용하지 않으며,
타입 선언에는 괄호() 안에 들어간 인수 목록을 런타임에서 갖는 ‘익명’ 타입이다.
또한 필드의 길이(갯수), 위치, 이름이 지정된다.
그리고 코드 값과 레코드 유형은 인수 목록 및 단순화된 함수 유형 매개변수 목록과 유사하게 작성된다.
이것은 다음으로 알아볼 구조분해와 유사한데, 마찬가지로 JS를 했다면 정말 눈에 익는다.
(int, String, {bool isValid}) triple = (1, "one", isValid: true);
위의 Records 선언문은 아래와 매우 유사하다.
typedef F = void Function(int, String, {bool isValid});
void callIt(F f) => f(1, "one", isValid: true);
positional 필드에 기록된 이름은 전적으로 문서화 목적으로만 사용되며 프로그램에 아무런 영향을 미치지 않는다.
(double value, String name, {String isValid}) another = (
3.14, "Pi", isValid: "real");
예를 들어 위 코드에서 value
, name
은 어떤 영향도 갖지 않는다. 오직 named 필드에 기록된 isValid
만 접근할 수 있다.
Records값은 구조분해가 가능하다. 주로 아래와 같은 패턴으로 분해한다.
switch (triple) {
case (int value, String name, isValid: bool ok): // ....
}
개별 필드는 명명된 이름(getter)를 사용하여 접근할 수도 있으며, positional 필드의 경우 $1, $2 등을 사용하고 named 필드의 경우 이름 자체를 사용할 수 있다.
int value = triple.$1;
String name = triple.$2;
bool ok = triple.isValid;
Records 유형은 동일한 모양을 가진 다른 레코드 유형의 하위 유형이 될 수 있으며, 이전 레코드 유형의 필드 유형이 다른 레코드 유형의 해당 필드 유형의 하위 유형인 경우에만 가능하다.
즉, (int, String, {bool isValid})
는 모양이 같고 필드 유형이 점 단위의 하위 유형이기 때문에 (num, String, {Object isValid})
의 하위 유형이다.
모양이 다른 Records 유형은 비록 Records라고 하더라도 서로 관련이 없다.