Rust 치트시트
마지막 업데이트
Hello World 및 구조
Rust 프로그램은 fn main에서 시작하며, 문은 세미콜론으로 끝납니다.
| 작업 | 문법 |
|---|---|
| 진입점 | fn main() { ... } |
| 한 줄 출력 | println!("Hello, World!"); |
| 값과 함께 출력 | println!("{} is {}", name, age); |
| 디버그 형식 출력 | println!("{:?}", value); |
| 한 줄 주석 | // comment |
| 모듈에서 항목 가져오기 | use std::collections::HashMap; |
| 빌드 및 실행 | cargo run |
| 릴리스 바이너리 빌드 | cargo build --release |
변수 및 타입 (let / mut)
바인딩은 기본적으로 불변이며, mut을 붙이면 재할당을 허용합니다.
| 작업 | 문법 |
|---|---|
| 불변 바인딩 | let x = 5; |
| 가변 바인딩 | let mut count = 0; |
| 명시적 타입 | let age: u32 = 30; |
| 상수 | const MAX: u32 = 100; |
| 섀도잉 | let x = x + 1; |
| 정수 타입 | i32, u32, i64, usize |
| 기타 스칼라 | f64, bool, char |
| 튜플 | let pair: (i32, &str) = (1, "a"); |
| 타입 변환 | let f = x as f64; |
제어 흐름
if는 표현식이며, Rust에는 세 가지 반복 형태가 있습니다.
| 작업 | 문법 |
|---|---|
| if / else | if x > 0 { ... } else { ... } |
| 표현식으로서의 if | let y = if x > 0 { 1 } else { -1 }; |
| 무한 반복 | loop { ... } |
| 값을 반환하는 loop | let v = loop { break 5; }; |
| while 반복문 | while x < 100 { ... } |
| 범위 순회 for | for i in 0..10 { ... } |
| 컬렉션 순회 for | for item in &items { ... } |
| break / continue | break;, continue; |
함수
마지막 표현식(세미콜론 없음)이 반환값입니다.
| 작업 | 문법 |
|---|---|
| 기본 함수 | fn add(a: i32, b: i32) -> i32 { a + b } |
| 명시적 반환 | fn f() -> i32 { return 5; } |
| 반환값 없음 | fn log(msg: &str) { ... } |
| 참조 받기 | fn len(s: &String) -> usize { s.len() } |
| 클로저 | let add = |a, b| a + b; |
| 타입이 있는 클로저 | let sq = |x: i32| -> i32 { x * x }; |
| 인자로서의 함수 | fn apply(f: impl Fn(i32) -> i32) { ... } |
소유권 및 빌림
각 값에는 소유자가 하나이고, 참조는 소유권을 가져가지 않고 빌립니다.
| 작업 | 문법 |
|---|---|
| 이동 (소유권 이전) | let b = a; (a는 더 이상 유효하지 않음) |
| 복제 (깊은 복사) | let b = a.clone(); |
| 불변 빌림 | let r = &x; |
| 가변 빌림 | let r = &mut x; |
| 함수에서 빌림 | fn read(s: &String) { ... } |
| 역참조 | *r |
| 빌림 규칙 | 한 번에 여러 & 또는 하나의 &mut, 둘 다는 안 됨 |
| 슬라이스 (범위를 빌림) | let part = &arr[1..3]; |
구조체 및 열거형
구조체는 관련 데이터를 묶고, 열거형은 여러 변형 중 하나인 값을 모델링합니다.
| 작업 | 문법 |
|---|---|
| 구조체 정의 | struct Point { x: i32, y: i32 } |
| 인스턴스 생성 | let p = Point { x: 1, y: 2 }; |
| 필드 접근 | p.x |
| 튜플 구조체 | struct Pair(i32, i32); |
| 메서드 (impl 블록) | impl Point { fn dist(&self) -> f64 { ... } } |
| 연관 함수 | impl Point { fn new() -> Self { ... } } |
| 열거형 정의 | enum Shape { Circle(f64), Rect(f64, f64) } |
| 이름 있는 필드를 가진 열거형 | enum Msg { Move { x: i32, y: i32 } } |
| 트레이트 파생 | #[derive(Debug, Clone)] |
패턴 매칭 (match)
match는 값을 패턴과 비교하며 모든 경우를 빠짐없이 다뤄야 합니다.
| 작업 | 문법 |
|---|---|
| 값에 대한 매칭 | match x { 1 => "one", _ => "other" } |
| 열거형 매칭 | match shape { Shape::Circle(r) => ... } |
| 범위 매칭 | match n { 1..=5 => ..., _ => ... } |
| 가드와 함께 바인딩 | match x { n if n > 0 => ... } |
| 튜플 매칭 | match point { (0, y) => ..., (x, _) => ... } |
| if let (단일 패턴) | if let Some(v) = opt { ... } |
| while let | while let Some(v) = stack.pop() { ... } |
| 구조체 구조 분해 | let Point { x, y } = p; |
트레이트 및 제네릭
트레이트는 공유 동작을 정의하고, 제네릭은 코드가 여러 타입에서 동작하게 합니다.
| 작업 | 문법 |
|---|---|
| 트레이트 정의 | trait Area { fn area(&self) -> f64; } |
| 트레이트 구현 | impl Area for Circle { fn area(&self) -> f64 { ... } } |
| 기본 메서드 | trait Greet { fn hi(&self) { ... } } |
| 제네릭 함수 | fn largest<T: PartialOrd>(list: &[T]) -> &T { ... } |
| 제네릭 구조체 | struct Wrapper<T> { value: T } |
| 트레이트 바운드 (where) | fn f<T>(x: T) where T: Display { ... } |
| impl Trait 인자 | fn print(item: impl Display) { ... } |
| 트레이트 객체 | let shapes: Vec<Box<dyn Area>> = ...; |
오류 처리 (Result / Option)
Rust는 값의 부재를 Option으로, 복구 가능한 오류를 Result로 모델링합니다.
| 작업 | 문법 |
|---|---|
| 선택적 값 | Option<T>: Some(v) 또는 None |
| Result 타입 | Result<T, E>: Ok(v) 또는 Err(e) |
| Result 반환 | fn read() -> Result<String, Error> { ... } |
| ? 로 전파 | let data = read()?; |
| unwrap (None/Err이면 패닉) | opt.unwrap() |
| 기본값 | opt.unwrap_or(0) |
| 값 매핑 | opt.map(|v| v + 1) |
| 양쪽 갈래 처리 | match res { Ok(v) => ..., Err(e) => ... } |
| Option을 Result로 변환 | opt.ok_or("missing")? |
자주 쓰는 컬렉션 (Vec / HashMap)
Vec은 늘어나는 배열이고, HashMap은 키-값 저장소입니다.
| 작업 | 문법 |
|---|---|
| 벡터 생성 | let mut v: Vec<i32> = Vec::new(); |
| 벡터 리터럴 | let v = vec![1, 2, 3]; |
| push / pop | v.push(4);, v.pop(); |
| 인덱스 접근 | v[0] |
| 안전한 접근 | v.get(0)은 Option<&T>를 반환 |
| 순회 | for x in &v { ... } |
| 길이 | v.len() |
| 맵 생성 | let mut m: HashMap<String, i32> = HashMap::new(); |
| 삽입 / 가져오기 | m.insert(k, v);, m.get(&k) |
| Entry API | *m.entry(k).or_insert(0) += 1; |
가장 자주 쓰는 Rust 문법을 한 페이지에 담았습니다. 이 Rust 치트시트는 언어 핵심을 위한 빠른 참조 자료입니다 - 변수와 가변성, 소유권과 빌림, 구조체와 열거형, 패턴 매칭, 트레이트와 제네릭, 그리고 Rust의 오류 처리를 떠받치는 Result와 Option 타입을 다룹니다.
여기 나오는 모든 내용은 최근 안정 툴체인에서 컴파일되는 표준 Rust입니다. 필요한 것을 복사하거나, Rust 플레이그라운드에서 모든 코드를 바로 실행해 보세요 - cargo 설치가 필요 없습니다.
Rust 치트시트 자주 묻는 질문
이 Rust 치트시트는 무료인가요?
Rust에서 소유권과 빌림이란 무엇인가요?
&x, 가변 빌림은 &mut x입니다. 컴파일러는 한 가지 규칙을 강제합니다: 한 번에 여러 불변 빌림을 갖거나 정확히 하나의 가변 빌림을 가질 수 있으며, 이를 통해 컴파일 시점에 데이터 경합을 방지합니다.Rust에서 Result와 Option의 차이는 무엇인가요?
Option<T>는 값이 없을 수도 있음을 나타냅니다 - Some(v) 또는 None 중 하나이며, 보고할 오류는 없고 그저 값이 빠져 있을 때 사용합니다. Result<T, E>는 실패할 수 있는 연산을 나타냅니다 - Ok(v) 또는 Err(e) 중 하나이며, 무언가 잘못되면 오류 값을 담습니다. "있을 수도 있음"에는 Option을, "이것은 실패할 수 있음"에는 Result를 사용하세요. ? 연산자는 둘 다 전파합니다.