러스트의 Enum(열거형)은 C/C++의 enum과는 근본적으로 다릅니다: 이들은 연관된 데이터를 저장할 수 있으며 상태와 오류 모델링에 적합합니다. 이를 통해 타입-안전한 유한 상태 기계, 다양한 유형의 Option/Result를 구축하고 '합집합 타입' 패턴을 구현합니다. 역사적으로 유사한 구조는 엄격하게 분리된 변수를 가진 엔티티의 변형을 설명하기 위해 함수형 언어에서 사용되었습니다.
문제: 모든 상태의 변형을 표현하고 각 처리 경우가 필수적이며 실수로 분기 처리가 누락되지 않도록 하는 것입니다. 프로젝트 전역에서 오류를 이러한 표현력 있는 구조 없이 타입화하는 것은 어렵습니다.
해결책: 연관된 데이터와 패턴 매칭이 있는 enum은 제어를 제공합니다 - 각 분기는 컴파일러에 의해 검사되며, 철저함이 보장됩니다. 또한, Result와 Option에 대해 이미 많은 보조 메서드가 구현되어 있습니다.
코드 예:
enum NetworkState { Disconnected, Connecting(u32), // 시도 번호 Connected(String), Error(String), } fn print_state(state: NetworkState) { match state { NetworkState::Disconnected => println!("Net: disconnected"), NetworkState::Connecting(count) => println!("Net: connecting (attempt {})", count), NetworkState::Connected(addr) => println!("Net: connected to {}", addr), NetworkState::Error(msg) => println!("Net error: {}", msg), } }
주요 특징:
_ 없이 enum의 분기를 부분적으로 처리할 수 있는가?
컴파일러는 비철저(enum이 exhaustive하지 않은 경우)한 경우에 대해 닫히지 않은 경우를 금지하지만, _를 사용하여 처리되지 않은 분기는 "흡수"될 수 있습니다. 미래의 변경 사항이 간과되지 않도록 임상적으로 중요한 분기에서는 _를 피해야 합니다.
패턴 매칭 시 연관된 값이 참조되는 경우와 복사되는 경우는?
패턴 매칭 시 연관된 데이터는 기본적으로 이동(move)됩니다. 단지 조회가 필요할 경우 참조를 사용하세요:
match &state { NetworkState::Connected(addr) => println!("by ref: {}", addr), _ => {} }
하나의 구조체에서 이름이 겹치는 두 enum을 사용할 수 있는가?
가능합니다. 하지만 변형의 이름은 enum 프리픽스를 사용해야 합니다. 이는 충돌을 방지하고 코드를 자가 문서화되도록 만듭니다 (예: Status::Ok vs NetworkState::Ok).
_ 사용_ =>)의 남용코드에서 Result<T, E> 처리는 항상 _ =>를 통해 catch-all을 가지며, 새로운 오류는(enum 확장 시) 누락됩니다 - 오류의 묵인 손실이 발생합니다.
장점:
단점:
철저성 매칭이 사용되며, 각 Enum 변형이 명시적으로 처리되거나 안정된 동작이 없는 분기에서 panic합니다.
장점:
단점: