+Folder는 생성 시 자식 배열을 복사하고 이후 추가 API를 제공하지 않는다. Folder는 record라서 컴파일러가 만든 동등성 비교가 자식 배열을 참조로 비교한다. 내용이 같은 두 폴더도 같은 배열을 공유하지 않으면 같지 않다. 구조를 변경하는 트리로 확장한다면 순환 연결을 막고, 합계의 범위와 갱신 시점을 정해야 한다.
TypeScript 예제
호출부가 파일과 폴더를 구별하지 않도록 공통 항목 Entry를 둔다. 파일은 자기 크기를, 폴더는 자식 크기의 합을 돌려주므로 중첩 구조를 계산하는 책임이 Folder 안에 모인다.
// 호출부가 잎과 묶음을 같은 방식으로 읽을 수 있는 약속이다.
abstract class Entry { abstract get bytes(): bigint; }
class FileEntry extends Entry {
constructor(private readonly length: bigint) { super(); }
override get bytes(): bigint { return this.length; }
}
// 자식 종류를 검사하는 대신 공통 속성을 읽어 재귀 합계를 낸다.
class Folder extends Entry {
private readonly children: readonly Entry[];
constructor(children: readonly Entry[]) { super(); this.children = [...children]; }
override get bytes(): bigint {
return this.children.reduce((total, child) => total + child.bytes, 0n);
}
}
const entries: Entry[] = [
new FileEntry(7n),
new Folder([new FileEntry(5n), new Folder([new FileEntry(10n), new FileEntry(20n)])]),
];
for (const entry of entries) console.log(entry.bytes.toString());
7
35
파일 크기는 정수이므로 TypeScript에서는 bigint를 사용하고 출력할 때 문자열로 바꿨다. 생성 시 자식 배열을 복사하며 실제 파일 시스템에는 접근하지 않는다.