Rust Option
Rust에는 null이 없어요. 값이 없을 수도 있다면, 그 사실을 Option을 써서 타입에 직접 드러내요. 처음에는 괜히 번거로운 절차처럼 느껴질 수 있지만, 덕분에 버그 한 종류가 통째로 사라져요. 다른 언어에서 셀 수 없이 많은 프로그램을 죽게 만든 “null 참조” 말이에요.
Option은 이렇게 생겼어요
섹션 제목: “Option은 이렇게 생겼어요”Option은 배리언트가 두 개인 열거형이에요.
enum Option<T> { Some(T), // 값이 있어요 None, // 값이 없어요}사실 이미 본 적이 있어요. 벡터의 .get()과 HashMap의 .get()이 둘 다 Option을 반환하거든요.
Option 만들기
섹션 제목: “Option 만들기”fn main() { let has_value: Option<i32> = Some(5); let no_value: Option<i32> = None;
println!("{:?}", has_value); println!("{:?}", no_value);}실행 결과:
Some(5)Nonematch로 Option 다루기
섹션 제목: “match로 Option 다루기”값을 안전하게 꺼내는 방법은 match예요. Rust는 두 경우를 모두 처리하도록 강제하기 때문에, “값이 없는” 경우를 실수로 빠뜨릴 수가 없어요.
fn main() { let age: Option<i32> = Some(30);
match age { Some(value) => println!("나이: {value}살"), None => println!("나이가 입력되지 않았어요"), }}실제와 비슷한 예제
섹션 제목: “실제와 비슷한 예제”fn find_user(id: u32) -> Option<&'static str> { if id == 1 { Some("Alice") } else { None }}
fn main() { match find_user(1) { Some(name) => println!("찾았어요: {name}"), None => println!("사용자를 찾을 수 없어요"), }
match find_user(99) { Some(name) => println!("찾았어요: {name}"), None => println!("사용자를 찾을 수 없어요"), }}실행 결과:
찾았어요: Alice사용자를 찾을 수 없어요사용자를 찾지 못했을 때 null을 반환하거나 예외를 던지는 대신, 함수의 반환 타입 자체가 모든 호출자에게 “아무것도 못 찾을 수도 있어요”라고 알려 줘요. 그리고 컴파일러는 호출자가 그 가능성을 무시하지 못하게 해요.
지름길: unwrap_or와 unwrap
섹션 제목: “지름길: unwrap_or와 unwrap”간단한 경우라면 match를 통째로 쓰는 게 과하게 느껴질 수 있어요. 그럴 때 쓸 수 있는 지름길이 몇 가지 있어요.
fn main() { let age: Option<i32> = None;
let value = age.unwrap_or(0); // 값이 없으면 0을 대신 써요 println!("{value}");}.unwrap()도 있어요. 값을 바로 꺼내 주지만, None이면 패닉(panic)이 일어나서 프로그램이 멈춰요.
let age: Option<i32> = Some(30);let value = age.unwrap(); // age가 Some이니까 여기서는 괜찮아요연습 문제
섹션 제목: “연습 문제”1. 첫 번째 짝수
섹션 제목: “1. 첫 번째 짝수”슬라이스에서 첫 번째 짝수를 반환하고, 짝수가 없으면 None을 반환하는 fn first_even(numbers: &[i32]) -> Option<i32>를 작성해 보세요. [3, 7, 8, 10]의 결과는 match로, [1, 3, 5]의 결과는 .unwrap_or(0)으로 출력하세요. 힌트: 슬라이스를 돌다가 n % 2 == 0이 되는 순간 return Some(n)을 하고, 반복문이 끝난 뒤에는 None을 반환하세요.
정답 보기
fn first_even(numbers: &[i32]) -> Option<i32> { for &n in numbers { if n % 2 == 0 { return Some(n); } } None}
fn main() { match first_even(&[3, 7, 8, 10]) { Some(n) => println!("첫 번째 짝수: {n}"), None => println!("짝수가 없어요"), }
let fallback = first_even(&[1, 3, 5]).unwrap_or(0); println!("기본값 적용: {fallback}");}실행 결과:
첫 번째 짝수: 8기본값 적용: 02. 설정값 찾기
섹션 제목: “2. 설정값 찾기”"volume"이 80으로 설정된 항목 하나만 들어 있는 설정 HashMap을 만드세요. 그런 다음 키 "volume"과 "brightness"를 돌면서, 값이 있으면 그 값을, 없으면 “설정되지 않았다”는 메시지를 출력하세요. 힌트: HashMap의 .get(key)는 Option을 반환하니까, 바로 match할 수 있어요.
정답 보기
use std::collections::HashMap;
fn main() { let mut settings = HashMap::new(); settings.insert("volume", 80);
for key in ["volume", "brightness"] { match settings.get(key) { Some(value) => println!("{key} = {value}"), None => println!("{key}: 설정되지 않았어요"), } }}실행 결과:
volume = 80brightness: 설정되지 않았어요Option<T>는 있을 수도 있고 없을 수도 있는 값을 나타내요. Rust에는null이 없어요.Some(value)는 값을 담고 있고,None은 아무것도 없다는 뜻이에요.match는 두 경우를 모두 안전하게 처리하는 방법이에요. 컴파일러는 한쪽을 빠뜨리지 못하게 해요..unwrap_or(default)는 기본값을 대신 줘요..unwrap()은 값이None이면 패닉을 일으키니까 아껴서 쓰세요.
이해도 점검
섹션 제목: “이해도 점검”이해도 점검
1. 값이 없을 수도 있을 때, Rust는 null 대신 무엇을 쓰나요?
2. None 값에 .unwrap()을 호출하면 어떻게 되나요?
3. age가 None일 때 age.unwrap_or(0)은 어떻게 동작하나요?
4. match가 Option에서 값을 꺼내는 안전한 방법으로 여겨지는 이유는 무엇인가요?
5. 이 페이지에서 언급한 메서드 중 이미 Option을 반환하는 것은 무엇인가요?
점수: 0 / 5
더 알아보기
섹션 제목: “더 알아보기”- 열거형 정의하기 — The Rust Programming Language 한국어판: 공식 책의 열거형 장이에요. 마지막 절 “Option 열거형이 널 값보다 좋은 점들”에서 Rust가 왜
null대신Option을 쓰는지 설명해요. std::option— 표준 라이브러리 문서 (영어):Option으로 할 수 있는 모든 것을 한눈에 정리했어요.map,and_then,is_some같은 편리한 메서드도 나와요.- Option & unwrap — Rust by Example (영어):
match,unwrap, 그리고 언제 패닉이 일어나는지를 보여 주는 짧은 실행 예제예요. Option<T>— 표준 라이브러리 문서 (영어): 모든 메서드 목록이에요. 메서드마다 복사해서 써 볼 수 있는 작은 예제가 붙어 있어요.