학습 결과: 작은 도메인을 레코드와 컬렉션으로 표현하고, if, match, for가 각각 답하는 질문에 맞춰 제어 형식을 고릅니다.
선행 학습: 값과 함수를 마치고 바인딩, 타입 표기, 매개변수, 함수 결과를 이해해야 합니다.
작업마다 일정한 모양 주기
data-control.tpz를 만드세요.
record StudyTask {
title: string,
minutes: int,
done: bool = false,
}
function pace(task: StudyTask) -> string {
if task.done {
return "done"
}
match task.minutes {
case 1..15 => "quick"
case 16..30 => "focused"
case _ => "deep"
}
}
let tasks: Array<StudyTask> = [
StudyTask { title: "Run first program", minutes: 10, done: true },
StudyTask { title: "Build application", minutes: 25 },
]
let mut remaining = 0
for task in tasks {
if !task.done {
remaining = remaining + task.minutes
}
print("{task.title}: {pace(task)}")
}
print("remaining: {remaining} minutes")같은 두 단계 흐름으로 실행합니다.
topaz check data-control.tpz
topaz run data-control.tpz
출력은 다음과 같습니다.
Run first program: done
Build application: focused
remaining: 25 minutes세 가지 결정 따라가기
StudyTask는 명목 레코드입니다. 이름과 필드가 하나의 도메인 값 종류를 정의합니다. done의 기본값은 false이므로 두 번째 생성자에서는 이 필드를 생략했습니다. Array<StudyTask>는 tasks가 이 레코드들을 순서대로 담는 컬렉션임을 나타냅니다.
for는 작업을 배열 순서대로 방문하므로 출력도 같은 순서를 따릅니다. 반복문 안의 if !task.done은 예/아니요 질문 하나에 답하고, 끝나지 않은 작업에 대해서만 remaining을 늘립니다.
pace는 다른 질문을 처리합니다. 첫 if는 끝난 작업에서 일찍 반환합니다. 이어지는 match는 남은 minutes를 범위별로 분류하며, 각 갈래의 문자열이 함수 결과가 됩니다.
선택: Array, Map, Set
이 학습 계획처럼 순서와 중복이 의미가 있다면 Array를 사용하세요. 핵심 동작이 키로 값을 찾는 것이라면 Map, 위치보다 유일성이 중요하다면 Set이 알맞습니다. 현재 항목 수가 아니라 사용자에게 보여야 할 동작을 기준으로 컬렉션을 고르세요.
직접 해보기
배열의 세 번째 항목으로 StudyTask { title: "Review output", minutes: 5, done: true }를 추가하세요. 어떤 줄이 새로 생기며 remaining은 바뀔까요?
정답 보기
Review output: done이 새로 출력됩니다. 추가한 작업은 이미 끝났으므로 if 본문이 실행되지 않고, remaining은 25 minutes로 유지됩니다.
다음 단계로 넘어갈 준비
StudyTask가 레코드인 이유, 컬렉션이 Array인 이유, 순회에 for를 쓰는 이유, 합산에 if를 쓰는 이유, 분류에 match를 쓰는 이유를 설명할 수 있다면 준비되었습니다.
독립된 규칙은 패턴과 제어 흐름, 레코드와 명목 데이터, 컬렉션과 컴프리헨션에서 확인하세요. 실패와 리소스로 계속하세요.