Option Enum 다시 살펴보기
Coddy Rust 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 61개 중 17번째.
Rust에서 이미 Option<T>를 접해 보셨을 것입니다. 이는 존재할 수도 있고 존재하지 않을 수도 있는 값을 나타내는 표준 열거형입니다. 이제 이를 OOP의 관점에서 살펴보겠습니다. Option은 단순한 열거형이 아니라, nullable 값을 안전하고 우아하게 처리할 수 있도록 해 주는 강력한 내장 메서드를 갖춘 타입입니다.
매번 매칭하는 대신, Option 값에 직접 메서드를 사용할 수 있습니다. unwrap_or 메서드는 내부 값이 존재하면 그 값을 반환하고, 그렇지 않으면 사용자가 제공한 기본값을 반환합니다.
let maybe_name: Option<String> = Some(String::from("Alice"));
let name = maybe_name.unwrap_or(String::from("Guest"));
println!("{}", name); // Alice
let empty: Option<String> = None;
let fallback = empty.unwrap_or(String::from("Guest"));
println!("{}", fallback); // Guest
map method는 내부 값이 exists하는 경우 이를 변환하고, None은 변경하지 않은 채로 둡니다. 이를 통해 None을 계속 확인하지 않고도 작업을 연쇄적으로 수행할 수 있습니다:
let maybe_num: Option<i32> = Some(5);
let doubled = maybe_num.map(|x| x * 2);
println!("{:?}", doubled); // Some(10)
let nothing: Option<i32> = None;
let still_nothing = nothing.map(|x| x * 2);
println!("{:?}", still_nothing); // None
이러한 메서드는 OOP 원칙을 구현합니다. Option 타입은 "값이 있을 수도 있음"이라는 개념을 캡슐화하고, 이를 다루기 위한 깔끔한 인터페이스를 제공합니다. 객체를 검사하기 위한 외부 로직을 작성하는 대신 객체에서 메서드를 호출합니다.
챌린지
쉬움Option 메서드를 사용하여 선택적 데이터를 유연하게 처리하는 사용자 프로필 시스템을 만들어 봅시다. 사용자에게 닉네임이 설정되어 있을 수도 있고, 없을 수도 있습니다. 명시적인 매칭 없이도 시스템이 두 경우를 모두 우아하게 처리하도록 합니다.
코드를 정리하기 위해 두 개의 파일을 만듭니다:
profile.rs: 두 개의 필드인username(String)과nickname(Option<String>)을 포함하는 publicProfile구조체를 Define합니다. 다음을 Implement합니다:- username과 optional nickname을 받는
newconstructor - nickname이 exists하면 nickname을, 그렇지 않으면 fallback으로 username을 Returns하는
display_namemethod: 이를 처리하려면unwrap_or를 사용합니다 - nickname이 exists하면 대괄호로 감싼 nickname(예:
"[CoolNick]")이 포함된Option<String>을, nickname이 없으면None을 Returns하는formatted_nicknamemethod: 값을 변환하려면map을 사용합니다
- username과 optional nickname을 받는
main.rs: profile 모듈을 가져오고 두 개의 프로필을 만듭니다. 하나에는 nickname이 있고 다른 하나에는 없습니다. 각 프로필에서 두 method를 모두 사용하여Optionmethod가 present 및 absent 값을 어떻게 다르게 처리하는지 보여 줍니다.
formatted_nickname method는 Option을 Returns하므로 출력할 때 debug formatting({:?})을 사용합니다.
출력은 두 프로필을 모두 표시하며 다음의 정확한 형식을 따라야 합니다:
Display name: {name}
Formatted nickname: {option}
Display name: {name}
Formatted nickname: {option}예를 들어 username "alice"에 nickname "Ace"가 있는 프로필과, nickname이 없는 username "bob" 프로필이 있다면 출력은 다음과 같습니다:
Display name: Ace
Formatted nickname: Some("[Ace]")
Display name: bob
Formatted nickname: None세 개의 입력을 받습니다. 첫 번째 username, 첫 번째 사용자의 nickname, 그리고 nickname이 없는 두 번째 username입니다.
직접 해보기
mod profile;
use profile::Profile;
fn main() {
// 입력 읽기
let mut input1 = String::new();
std::io::stdin().read_line(&mut input1).expect("Failed to read line");
let username1 = input1.trim().to_string();
let mut input2 = String::new();
std::io::stdin().read_line(&mut input2).expect("Failed to read line");
let nickname1 = input2.trim().to_string();
let mut input3 = String::new();
std::io::stdin().read_line(&mut input3).expect("Failed to read line");
let username2 = input3.trim().to_string();
// TODO: username1과 nickname1으로 첫 번째 프로필 생성 (Some)
// TODO: Create second profile with username2 and no nickname (None)
// TODO: Print display_name and formatted_nickname for first profile
// Use {:?} for formatted_nickname since it returns an Option
// TODO: Print display_name and formatted_nickname for second profile
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 Rust 컴파일러