형식 상태 빌더
형식 시스템에 유효성을 표현해 보세요.
형식 상태 빌더은(는) CoddyKit의 무료 Learn Rust Coding 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Learn Rust Coding 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Learn Rust Coding 강의에는 총 4개의 강의가 포함되어 있습니다.
일반 빌더의 문제
일반 빌더에서는 필수 필드가 설정되기 전을 포함하여 언제든 build()를 호출할 수 있습니다. 그러면 누락된 데이터가 실행 시간 패닉이나 Err로 나타납니다.
타입 상태 빌더는 이 검사를 컴파일 시간으로 옮깁니다. 필수 단계를 잊으면 컴파일에 실패합니다.
타입에 상태 인코딩하기
핵심은 완료된 단계를 나타내는 표식 타입을 기준으로 빌더를 제네릭으로 만드는 것입니다. 각 필드를 설정할 때마다 빌더의 타입이 바뀝니다.
모든 필수 표식이 "set" 상태에 도달한 경우에만 build() 메서드를 사용할 수 있습니다.
struct Missing;
struct Set;표식을 기준으로 제네릭화한 빌더
각 필수 필드의 상태에 대한 타입 매개변수를 빌더에 지정합니다. PhantomData는 실제 데이터를 저장하지 않고 표식을 전달합니다.
use std::marker::PhantomData;
struct ReqBuilder<H, U> {
url: Option<String>,
method: Option<String>,
_state: PhantomData<(H, U)>,
}시작 상태
생성자는 모든 필수 표식이 Missing인 빌더를 반환합니다. 이 시점에는 build()가 존재하지 않으므로 타입 시스템은 객체가 불완전하다는 것을 알 수 있습니다.
impl ReqBuilder<Missing, Missing> {
fn new() -> Self {
ReqBuilder { url: None, method: None, _state: PhantomData }
}
}표식 전환하기
설정 메서드는 기존 빌더를 소비하고 해당 필드의 표식이 Set으로 바뀐 새 빌더를 반환합니다. 다른 표식은 타입 매개변수를 제네릭으로 유지하여 보존합니다.
impl<U> ReqBuilder<Missing, U> {
fn url(self, url: &str) -> ReqBuilder<Set, U> {
ReqBuilder { url: Some(url.to_string()),
method: self.method, _state: PhantomData }
}
}두 번째 전환
메서드를 설정하는 과정도 같은 방식으로 작동합니다. 두 번째 표식을 Missing에서 Set으로 바꾸고 첫 번째 표식은 그대로 둡니다.
impl<H> ReqBuilder<H, Missing> {
fn method(self, m: &str) -> ReqBuilder<H, Set> {
ReqBuilder { url: self.url,
method: Some(m.to_string()), _state: PhantomData }
}
}모두 설정된 경우에만 build() 사용 가능
중요한 점은 build()가 ReqBuilder<Set, Set>에 대해서만 구현된다는 것입니다. 다른 상태에는 해당 메서드가 전혀 없으므로 호출하면 컴파일에 실패합니다.
내부의 unwrap 호출은 두 필드가 모두 존재한다는 것을 타입이 증명하므로 절대 패닉을 일으킬 수 없습니다.
struct Request { url: String, method: String }
impl ReqBuilder<Set, Set> {
fn build(self) -> Request {
Request { url: self.url.unwrap(), method: self.method.unwrap() }
}
}전체 연결하기
올바른 호출 연결은 각 호출이 빌더를 build()가 존재하는 ReqBuilder<Set, Set>로 이동시키므로 문제없이 컴파일됩니다.
fn demo() -> Request {
ReqBuilder::new()
.url("https://example.com")
.method("GET")
.build()
}원하는 컴파일 오류
필수 단계를 건너뛰면 컴파일러가 거부합니다. ReqBuilder<Set, Missing>에서 build()를 호출하면 "no method named build"라는 오류가 보고되어 프로그램이 실행되기 전에 누락을 발견할 수 있습니다.
// ReqBuilder::new().url("x").build();
// error: no method named `build` found for
// ReqBuilder<Set, Missing>독립적으로 실행 가능한 버전
이 최소 프로그램은 필수 필드 하나를 사용하여 처음부터 끝까지 전체 전환 과정을 보여 줍니다. 프로그램은 컴파일된 후 빌드된 값을 출력합니다.
use std::marker::PhantomData;
struct Missing; struct Set;
struct B<N> { name: Option<String>, _s: PhantomData<N> }
impl B<Missing> {
fn new() -> Self { B { name: None, _s: PhantomData } }
fn name(self, n: &str) -> B<Set> {
B { name: Some(n.to_string()), _s: PhantomData }
}
}
impl B<Set> {
fn build(self) -> String { self.name.unwrap() }
}
fn main() {
let v = B::new().name("prod").build();
println!("built: {}", v);
}비용과 절충점
타입 상태 빌더는 표식이 제거되므로 실행 시간 오버헤드 없이 컴파일 시간 보장을 제공합니다. 그 대가로 타입 관련 코드가 더 필요하고, 필수 필드가 늘어날수록 구현 블록이 조합적으로 증가합니다.
불완전한 빌드를 구조적으로 불가능하게 만들어야 하는 API에 이 패턴을 사용하십시오.
빠른 확인
타입 상태 빌더에서 완전성을 실제로 보장하는 것이 무엇인지 확인해 보십시오.
정리
타입 상태 빌더는 각 필수 단계를 PhantomData로 전달되는 표식 타입 매개변수로 인코딩합니다. 설정 메서드는 빌더를 소비하고 하나의 표식이 Set으로 바뀐 새 타입을 반환합니다.
build()는 모든 표식이 Set인 상태에 대해서만 구현되므로, 단계를 잊으면 실행 시간 패닉이 아니라 컴파일 오류가 발생하며 실행 시간 비용도 전혀 들지 않습니다.
자주 묻는 질문
“형식 상태 빌더” 강의는 무료인가요?
네 — “형식 상태 빌더” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Learn Rust Coding 강의 전체를 잠금 해제할 수 있습니다. Learn Rust Coding 강의에는 총 4개의 강의가 포함되어 있습니다.
“형식 상태 빌더”에서 뭘 배우나요?
형식 시스템에 유효성을 표현해 보세요. 브라우저에서 직접 실행하는 실습 코드로 Learn Rust Coding을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Learn Rust Coding을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Learn Rust Coding은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“형식 상태 빌더” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Learn Rust Coding 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Learn Rust Coding 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 빌더 패턴
- 뉴타입 패턴
- 형식 상태 빌더
- Deref와 래퍼 사용성