가변 길이 레코드 배열
레코드 배열의 길이를 로우마다 다르게 하는 기능의 설계입니다. 중첩 필드를 먼저 읽어야 합니다 — 그 위에 얹는 것입니다.
1. 문제
레코드 그룹의 배열 길이는 컬럼 수입니다. Slot1.*·Slot2.*·Slot3.*이면 모든 로우가
길이 3입니다. 값을 두 개만 적은 로우도 세 번째 원소를 갖고, 그 원소는 타입의 빈 값으로 찹니다.
읽는 쪽에서는 그 원소가 적은 것인지 안 적은 것인지 알 수 없습니다. {Id:0, Count:0}이
「0개를 주는 슬롯」인지 「슬롯이 없음」인지 구별되지 않습니다. 그래서 소비하는 코드마다
「전부 0이면 없는 것으로 친다」를 손으로 적게 되고, 그 규칙은 어디에도 적혀 있지 않습니다.
그 레이아웃은 이것을 익스포터가 처리합니다 — 값이 있는
마지막 원소까지로 배열을 자릅니다. 두 워크북의 대조에서 우리 쪽 격차로 남은 것이 이것뿐입니다
(material 94행, language 1,376행).
2. 결정 — 뒤에서 절단
값이 없는 뒤쪽 원소를 버립니다. 가운데는 건드리지 않습 니다.
| 로우 | Slot1 | Slot2 | Slot3 | 나오는 길이 |
|---|---|---|---|---|
| 1 | 값 | 값 | 값 | 3 |
| 2 | 값 | 값 | 없음 | 2 |
| 3 | 값 | 없음 | 값 | 3 — 가운데는 그대로 |
| 4 | 없음 | 없음 | 없음 | 0 |
가운데를 지우지 않는 이유. 지우면 원소의 위치가 바뀝니다. Slot2에 적은 것이 로우마다
[0]이거나 [1]이 되고, 그러면 컬럼과 인덱스의 대응이 로우마다 다릅니다 — 컬럼에 이름을 붙여
적은 시트에서 그것을 뜻했을 리가 없습니다. 뒤에서만 자르면 인덱스 k는 언제나 Slot{k+1}
입니다.
「값이 없다」의 정의
레이아웃이 정합니다. 코어는 셀마다 Cell.HasValue 하나만 읽습니다.
| 레이아웃 | 값이 없는 셀 |
|---|---|
tabbit | 타입에 ?가 붙은 컬럼의 - (빈 칸과 없음) |
named-range | -, 그리고 빈 칸 |
파싱된 값으로 판정하지 않습니다. 0을 적은 셀 과 값이 없다고 적은 셀은 둘 다 0이 되므로,
값을 보면 작성자가 적은 0을 지우게 됩니다. 「비었다」는 셀의 성질이고 값의 성질이 아닙니다.
빈 칸으로도 판정하지 않습니다. 빈 칸은 그 타입이 읽는 값이고 — string?이면 빈 문자열입니다 —
빈 이름을 적은 원소를 지우는 것은 작성자가 적은 0을 지우는 것과 같은 일입니다.
원소는 멤버 전부가 값이 없을 때 비어 있습니다. 하나라도 있으면 그 원소는 남고, 값이 없는 멤버는 빈 값으로 나갑니다. 멤버마다 따로 자르면 한 원소의 멤버들이 서로 다른 인덱스에 놓입니다.
옵트인 설정
기본은 끔입니다. 켜면 배열이 짧아지고, 그것은 조용합니다 — serial field가 옵트인이 된
것과 같은 이유입니다. 소스 항목의
TrimTrailingArrayElements로 켭니다. 스칼라 배열도 같은 규칙으로 잘립니다 — 자르기는
「원소가 어디서 끝나는가」에 대한 답이고, 그 질문에 원소의 생김새는 상관이 없습니다. 배열
컬럼들이 필수 여부를 서로 다르게 적으면 첫 원소의 답을 씁니다.
다른 레이아웃은 이 설정을 읽지 않고 항상 자릅니다. 그 시트들의 규칙이 그것이고, 그 규칙은 그 레이아웃 파일 안에 있습니다.
3. 가운데 빈칸 — 기본은 거부
2절은 가운데를 유지한다고 정하였고, 그것은 여전히 맞습니다. 남아 있던 질문은 다른 것입니다 — 가운데가 빈 배열을 애초에 받을 것인가.
결정. 받지 않습니다. 가운데 빈칸은 어느 셀인지 함께 보고하고 변환을 멈춥니다. 받겠다고 적은 소스에서만 통과합니다.
| 로우 | Slot1 | Slot2 | Slot3 | 기본 | AllowArrayGaps |
|---|---|---|---|---|---|
| 1 | 값 | 값 | 값 | 3 | 3 |
| 2 | 값 | 값 | 없음 | 2 — 뒤에서 자름 | 2 |
| 3 | 값 | 없음 | 값 | 거부 | 3 — 가운데는 그대로 |
| 4 | 없음 | 없음 | 없음 | 0 | 0 |
근거 — 관대함이 통과시키는 것
가운데 빈칸은 거의 언제나 실수입니다. Slot2를 지우고 Slot3을 그대로 둔 것이 의도인
시트는 드물고, 의도였다면 그 자리에 뜻이 있는 값을 적었을 것입니다. 지금은 그것이 조용히 길이
3짜리 배열이 되어 나가고, 가운데 원소는 타입의 빈 값입니다 — 소비하는 쪽에서 「없음」과
「0」이 구별되지 않습니다.
이 도구의 역할이 정적 검증인데, 다른 익스포터가 검출하는 것을 통과시키고 있었습니다.
AllowArrayGaps — 받겠다고 적는 자리
소스 항목의 정식 프로퍼티입니다. TrimTrailingArrayElements와 같은 자리이고, 같은 이유로
그렇습니다 — 어느 레이아웃인지 몰라도 찾을 수 있어야 하는 질문이기 때문입니다. 배열을 가진
레이아웃이면 어느 것이든 이 질문을 받습니다.
| 값 | 뜻 |
|---|---|
false (기본) | 가운데 빈칸은 어느 셀인지 함께 보고하고 멈춥니다 |
true | 2절의 표대로 가운데를 유지하고 통과시킵니다 |
기본을 거부로 둔 것은 방향의 문제입니다. 관대한 기본은 실수를 데이터로 만들고, 엄격한 기본은 의도를 한 줄 적게 만듭니다. 뒤쪽이 되돌릴 수 있는 쪽입니다.