코드 갤러리

커뮤니티에서 공유된 유용한 Rust 코드 스니펫을 탐색하고 학습하세요.

28
전체 코드
8
초급
13
중급
7
고급
중급2024-01-28

JSON 파싱과 직렬화

serde를 사용한 JSON 데이터 처리 방법입니다.

#serde#JSON#웹개발
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug)]
struct User {
    name: String,
    age: u32,
    email: String,
}

fn main() {
    // JSON 문자열을 구조체로 역직렬화
    let json_str = r#"{"name":"Alice","age":30,"email":"alice@example.com"}"#;
    let user: User = serde_json::from_str(json_str).unwrap();
    println!("사용자: {:?}", user);
    
    // 구조체를 JSON으로 직렬화
    let new_user = User {
        name: "Bob".to_string(),
        age: 25,
        email: "bob@example.com".to_string(),
    };
    let json = serde_json::to_string_pretty(&new_user).unwrap();
    println!("JSON:\n{}", json);
}
web_dev_rust
156
892
45
중급2024-01-27

CLI 애플리케이션 만들기

clap을 사용한 명령줄 인터페이스 구현입니다.

#CLI#clap#도구
use clap::{Arg, Command};

fn main() {
    let matches = Command::new("myapp")
        .version("1.0")
        .author("Your Name")
        .about("CLI 예제 프로그램")
        .arg(
            Arg::new("input")
                .short('i')
                .long("input")
                .help("입력 파일 경로")
                .required(true)
        )
        .arg(
            Arg::new("verbose")
                .short('v')
                .long("verbose")
                .help("상세 출력 모드")
                .action(clap::ArgAction::SetTrue)
        )
        .get_matches();
    
    let input = matches.get_one::<String>("input").unwrap();
    let verbose = matches.get_flag("verbose");
    
    println!("입력 파일: {}", input);
    if verbose {
        println!("상세 모드 활성화");
    }
}
cli_builder
134
756
38
고급2024-01-26

HTTP 요청 보내기

reqwest를 사용한 HTTP 클라이언트 구현입니다.

#HTTP#reqwest#네트워크
use reqwest;
use tokio;

#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
    // GET 요청
    let response = reqwest::get("https://api.github.com/users/rust-lang")
        .await?
        .text()
        .await?;
    println!("응답: {}", &response[..200]);
    
    // POST 요청
    let client = reqwest::Client::new();
    let res = client
        .post("https://httpbin.org/post")
        .json(&serde_json::json!({
            "name": "Rust",
            "version": "1.75"
        }))
        .send()
        .await?;
    
    println!("상태: {}", res.status());
    Ok(())
}
network_guru
178
1023
52
초급2024-01-25

배열 합계 계산 - Iterator 활용

iterator를 사용하여 배열의 모든 요소를 효율적으로 합산하는 방법입니다.

#배열#iterator#초보자
fn main() {
    let numbers = vec![1, 2, 3, 4, 5];
    let sum: i32 = numbers.iter().sum();
    println!("합계: {}", sum);
}
중급2024-01-25

SQLite 데이터베이스 연동

rusqlite를 사용한 데이터베이스 CRUD 작업입니다.

#SQLite#데이터베이스#CRUD
use rusqlite::{Connection, Result};

#[derive(Debug)]
struct Person {
    id: i32,
    name: String,
    age: i32,
}

fn main() -> Result<()> {
    let conn = Connection::open_in_memory()?;
    
    // 테이블 생성
    conn.execute(
        "CREATE TABLE person (
            id INTEGER PRIMARY KEY,
            name TEXT NOT NULL,
            age INTEGER NOT NULL
        )",
        [],
    )?;
    
    // 데이터 삽입
    conn.execute(
        "INSERT INTO person (name, age) VALUES (?1, ?2)",
        ["Alice", "30"],
    )?;
    
    // 데이터 조회
    let mut stmt = conn.prepare("SELECT id, name, age FROM person")?;
    let person_iter = stmt.query_map([], |row| {
        Ok(Person {
            id: row.get(0)?,
            name: row.get(1)?,
            age: row.get(2)?,
        })
    })?;
    
    for person in person_iter {
        println!("찾음: {:?}", person?);
    }
    Ok(())
}
db_master
145
834
41
중급2024-01-24

에러 핸들링 패턴 - Result 타입

Result 타입을 활용한 안전한 에러 처리 패턴을 소개합니다.

#에러처리#Result#패턴
fn divide(a: f64, b: f64) -> Result<f64, String> {
    if b == 0.0 {
        Err("0으로 나눌 수 없습니다".to_string())
    } else {
        Ok(a / b)
    }
}

fn main() {
    match divide(10.0, 2.0) {
        Ok(result) => println!("결과: {}", result),
        Err(e) => println!("에러: {}", e),
    }
}
중급2024-01-24

간단한 게임 루프 구현

게임 개발의 기본이 되는 게임 루프 패턴입니다.

#게임#루프#시뮬레이션
use std::time::{Duration, Instant};
use std::thread;

struct GameState {
    player_x: f32,
    player_y: f32,
    score: u32,
    is_running: bool,
}

impl GameState {
    fn new() -> Self {
        GameState {
            player_x: 0.0,
            player_y: 0.0,
            score: 0,
            is_running: true,
        }
    }
    
    fn update(&mut self, delta_time: f32) {
        // 게임 로직 업데이트
        self.player_x += 1.0 * delta_time;
        self.score += 1;
        
        if self.score >= 100 {
            self.is_running = false;
        }
    }
    
    fn render(&self) {
        println!("위치: ({:.1}, {:.1}), 점수: {}", 
            self.player_x, self.player_y, self.score);
    }
}

fn main() {
    let mut game = GameState::new();
    let target_fps = 60;
    let frame_duration = Duration::from_secs_f32(1.0 / target_fps as f32);
    
    while game.is_running {
        let frame_start = Instant::now();
        
        game.update(frame_duration.as_secs_f32());
        game.render();
        
        let elapsed = frame_start.elapsed();
        if elapsed < frame_duration {
            thread::sleep(frame_duration - elapsed);
        }
    }
    println!("게임 종료! 최종 점수: {}", game.score);
}
game_rust
167
945
48
고급2024-01-23

Async/Await 기본 패턴

tokio를 사용한 비동기 프로그래밍의 기본 패턴입니다.

#async#tokio#동시성
use tokio;

#[tokio::main]
async fn main() {
    let result = fetch_data().await;
    println!("데이터: {:?}", result);
}

async fn fetch_data() -> Vec<i32> {
    // 비동기 작업 시뮬레이션
    tokio::time::sleep(
        tokio::time::Duration::from_secs(1)
    ).await;
    vec![1, 2, 3, 4, 5]
}
senior_dev
92
567
31
중급2024-01-23

해시 함수 사용하기

SHA-256 해시 생성과 비밀번호 해싱 예제입니다.

#해시#보안#암호화
use sha2::{Sha256, Digest};
use hex;

fn hash_string(input: &str) -> String {
    let mut hasher = Sha256::new();
    hasher.update(input.as_bytes());
    hex::encode(hasher.finalize())
}

fn verify_hash(input: &str, expected_hash: &str) -> bool {
    hash_string(input) == expected_hash
}

fn main() {
    let password = "my_secret_password";
    let hash = hash_string(password);
    
    println!("원본: {}", password);
    println!("해시: {}", hash);
    
    // 검증
    let is_valid = verify_hash("my_secret_password", &hash);
    println!("검증 결과: {}", is_valid);
    
    let is_invalid = verify_hash("wrong_password", &hash);
    println!("잘못된 비밀번호: {}", is_invalid);
}
crypto_dev
123
678
35
초급2024-01-22

구조체와 impl 블록

구조체를 정의하고 메서드를 구현하는 기본 패턴입니다.

#구조체#impl#기초
struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    fn new(width: u32, height: u32) -> Self {
        Rectangle { width, height }
    }

    fn area(&self) -> u32 {
        self.width * self.height
    }
}

fn main() {
    let rect = Rectangle::new(10, 20);
    println!("넓이: {}", rect.area());
}
crab_coder
56
345
15
초급2024-01-22

단위 테스트 작성하기

Rust의 내장 테스트 프레임워크 사용법입니다.

#테스트#TDD#품질
fn add(a: i32, b: i32) -> i32 {
    a + b
}

fn divide(a: f64, b: f64) -> Option<f64> {
    if b == 0.0 {
        None
    } else {
        Some(a / b)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_add() {
        assert_eq!(add(2, 3), 5);
        assert_eq!(add(-1, 1), 0);
        assert_eq!(add(0, 0), 0);
    }
    
    #[test]
    fn test_divide() {
        assert_eq!(divide(10.0, 2.0), Some(5.0));
        assert_eq!(divide(0.0, 5.0), Some(0.0));
    }
    
    #[test]
    fn test_divide_by_zero() {
        assert_eq!(divide(10.0, 0.0), None);
    }
    
    #[test]
    #[should_panic(expected = "assertion failed")]
    fn test_panic() {
        assert!(false, "assertion failed");
    }
}

fn main() {
    println!("테스트를 실행하려면: cargo test");
}
중급2024-01-21

Option 타입 활용법

Option 타입으로 null 안전성을 보장하는 방법입니다.

#Option#null안전#패턴매칭
fn find_user(id: u32) -> Option<String> {
    let users = vec![
        (1, "Alice"),
        (2, "Bob"),
        (3, "Charlie"),
    ];
    
    users.iter()
        .find(|(uid, _)| *uid == id)
        .map(|(_, name)| name.to_string())
}

fn main() {
    if let Some(user) = find_user(2) {
        println!("찾은 사용자: {}", user);
    } else {
        println!("사용자를 찾을 수 없습니다");
    }
}
중급2024-01-21

벤치마킹과 성능 측정

코드 성능을 측정하고 최적화하는 방법입니다.

#벤치마크#성능#최적화
use std::time::Instant;

fn fibonacci_recursive(n: u64) -> u64 {
    match n {
        0 => 0,
        1 => 1,
        _ => fibonacci_recursive(n - 1) + fibonacci_recursive(n - 2),
    }
}

fn fibonacci_iterative(n: u64) -> u64 {
    if n <= 1 {
        return n;
    }
    let mut a = 0;
    let mut b = 1;
    for _ in 2..=n {
        let temp = a + b;
        a = b;
        b = temp;
    }
    b
}

fn benchmark<F>(name: &str, f: F)
where
    F: Fn(),
{
    let start = Instant::now();
    f();
    let duration = start.elapsed();
    println!("{}: {:?}", name, duration);
}

fn main() {
    let n = 30;
    
    benchmark("재귀", || {
        let _ = fibonacci_recursive(n);
    });
    
    benchmark("반복", || {
        let _ = fibonacci_iterative(n);
    });
    
    println!("\n결과 검증:");
    println!("fib({}) = {}", n, fibonacci_iterative(n));
}
고급2024-01-20

트레이트 구현하기

트레이트를 정의하고 여러 타입에 구현하는 방법입니다.

#트레이트#다형성#OOP
trait Drawable {
    fn draw(&self);
}

struct Circle { radius: f64 }
struct Square { side: f64 }

impl Drawable for Circle {
    fn draw(&self) {
        println!("반지름 {}인 원 그리기", self.radius);
    }
}

impl Drawable for Square {
    fn draw(&self) {
        println!("변 {}인 사각형 그리기", self.side);
    }
}

fn main() {
    let shapes: Vec<Box<dyn Drawable>> = vec![
        Box::new(Circle { radius: 5.0 }),
        Box::new(Square { side: 10.0 }),
    ];
    
    for shape in shapes {
        shape.draw();
    }
}
고급2024-01-20

WebAssembly 함수 작성

Rust로 WebAssembly 모듈을 만드는 기초입니다.

#WebAssembly#WASM#웹
use wasm_bindgen::prelude::*;

// JavaScript에서 호출 가능한 함수
#[wasm_bindgen]
pub fn greet(name: &str) -> String {
    format!("안녕하세요, {}님!", name)
}

#[wasm_bindgen]
pub fn fibonacci(n: u32) -> u32 {
    match n {
        0 => 0,
        1 => 1,
        _ => {
            let mut a = 0;
            let mut b = 1;
            for _ in 2..=n {
                let temp = a + b;
                a = b;
                b = temp;
            }
            b
        }
    }
}

#[wasm_bindgen]
pub struct Calculator {
    value: f64,
}

#[wasm_bindgen]
impl Calculator {
    #[wasm_bindgen(constructor)]
    pub fn new() -> Calculator {
        Calculator { value: 0.0 }
    }
    
    pub fn add(&mut self, x: f64) {
        self.value += x;
    }
    
    pub fn get_value(&self) -> f64 {
        self.value
    }
}
wasm_builder
189
1156
56
초급2024-01-19

문자열 처리 기초

String과 &str의 차이점과 기본적인 문자열 처리 방법입니다.

#문자열#String#기초
fn main() {
    // String: 힙에 할당, 가변
    let mut s = String::from("Hello");
    s.push_str(", World!");
    
    // &str: 문자열 슬라이스, 불변
    let slice: &str = &s[0..5];
    
    println!("전체: {}", s);
    println!("슬라이스: {}", slice);
    
    // 문자열 분할
    for word in s.split(", ") {
        println!("단어: {}", word);
    }
}
중급2024-01-19

정규표현식 활용

regex 크레이트를 사용한 문자열 패턴 매칭입니다.

#정규표현식#regex#문자열
use regex::Regex;

fn main() {
    // 이메일 검증
    let email_re = Regex::new(
        r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
    ).unwrap();
    
    let emails = vec![
        "user@example.com",
        "invalid-email",
        "test.user@domain.co.kr",
    ];
    
    for email in &emails {
        let is_valid = email_re.is_match(email);
        println!("{}: {}", email, if is_valid { "유효" } else { "무효" });
    }
    
    // 캡처 그룹 사용
    let date_re = Regex::new(r"(\d{4})-(\d{2})-(\d{2})").unwrap();
    let text = "오늘 날짜는 2024-01-15입니다.";
    
    if let Some(caps) = date_re.captures(text) {
        println!("년: {}, 월: {}, 일: {}", 
            &caps[1], &caps[2], &caps[3]);
    }
    
    // 문자열 치환
    let result = date_re.replace(text, "$1년 $2월 $3일");
    println!("치환 결과: {}", result);
}
regex_master
134
789
42
고급2024-01-18

라이프타임 기초

라이프타임의 기본 개념과 함수에서의 사용법입니다.

#라이프타임#참조#메모리
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}

fn main() {
    let string1 = String::from("긴 문자열");
    let string2 = String::from("짧음");
    
    let result = longest(&string1, &string2);
    println!("더 긴 문자열: {}", result);
}
rust_mentor
112
678
42
초급2024-01-18

환경 변수와 설정 관리

dotenv와 config를 사용한 설정 관리입니다.

#환경변수#설정#dotenv
use std::env;
use dotenv::dotenv;

#[derive(Debug)]
struct Config {
    database_url: String,
    api_key: String,
    port: u16,
    debug_mode: bool,
}

impl Config {
    fn from_env() -> Result<Self, env::VarError> {
        Ok(Config {
            database_url: env::var("DATABASE_URL")?,
            api_key: env::var("API_KEY")?,
            port: env::var("PORT")
                .unwrap_or_else(|_| "8080".to_string())
                .parse()
                .unwrap_or(8080),
            debug_mode: env::var("DEBUG")
                .map(|v| v == "true" || v == "1")
                .unwrap_or(false),
        })
    }
}

fn main() {
    // .env 파일 로드
    dotenv().ok();
    
    // 환경 변수 설정 (테스트용)
    env::set_var("DATABASE_URL", "postgres://localhost/mydb");
    env::set_var("API_KEY", "secret_key_123");
    env::set_var("DEBUG", "true");
    
    match Config::from_env() {
        Ok(config) => {
            println!("설정 로드 완료:");
            println!("  DB: {}", config.database_url);
            println!("  포트: {}", config.port);
            println!("  디버그: {}", config.debug_mode);
        }
        Err(e) => println!("설정 오류: {}", e),
    }
}
env_config
87
534
25
초급2024-01-17

HashMap 기본 사용법

HashMap을 생성하고 데이터를 저장, 조회하는 방법입니다.

#HashMap#컬렉션#기초
use std::collections::HashMap;

fn main() {
    let mut scores = HashMap::new();
    
    // 데이터 삽입
    scores.insert("Blue", 10);
    scores.insert("Red", 50);
    
    // 데이터 조회
    let team = "Blue";
    if let Some(score) = scores.get(team) {
        println!("{} 팀 점수: {}", team, score);
    }
    
    // 반복문으로 순회
    for (key, value) in &scores {
        println!("{}: {}", key, value);
    }
}
cli_master
58
312
14
초급2024-01-17

로깅 시스템 구현

log와 env_logger를 사용한 로깅입니다.

#로깅#log#디버깅
use log::{debug, error, info, trace, warn};
use env_logger::Builder;
use std::io::Write;
use chrono::Local;

fn init_logger() {
    Builder::new()
        .format(|buf, record| {
            writeln!(
                buf,
                "{} [{}] - {}",
                Local::now().format("%Y-%m-%d %H:%M:%S"),
                record.level(),
                record.args()
            )
        })
        .filter(None, log::LevelFilter::Debug)
        .init();
}

fn process_data(data: &str) -> Result<(), String> {
    debug!("데이터 처리 시작: {}", data);
    
    if data.is_empty() {
        warn!("빈 데이터가 전달됨");
        return Err("빈 데이터".to_string());
    }
    
    info!("데이터 처리 중: {} 바이트", data.len());
    
    // 처리 로직...
    trace!("상세 처리 단계 완료");
    
    info!("데이터 처리 완료");
    Ok(())
}

fn main() {
    init_logger();
    
    info!("애플리케이션 시작");
    
    match process_data("테스트 데이터") {
        Ok(_) => info!("성공"),
        Err(e) => error!("실패: {}", e),
    }
    
    match process_data("") {
        Ok(_) => info!("성공"),
        Err(e) => warn!("경고: {}", e),
    }
}
log_expert
95
567
29
중급2024-01-16

클로저(Closure) 활용

클로저를 정의하고 다양한 상황에서 활용하는 방법입니다.

#클로저#함수형#고차함수
fn main() {
    // 기본 클로저
    let add = |a, b| a + b;
    println!("3 + 5 = {}", add(3, 5));
    
    // 환경 캡처
    let x = 10;
    let add_x = |n| n + x;
    println!("5 + x = {}", add_x(5));
    
    // 클로저를 인자로 전달
    let numbers = vec![1, 2, 3, 4, 5];
    let doubled: Vec<i32> = numbers
        .iter()
        .map(|n| n * 2)
        .collect();
    println!("두 배: {:?}", doubled);
}
고급2024-01-15

스레드 기본 사용법

std::thread를 사용한 멀티스레딩 기초입니다.

#스레드#동시성#병렬처리
use std::thread;
use std::time::Duration;

fn main() {
    let handle = thread::spawn(|| {
        for i in 1..5 {
            println!("스레드에서: ", i);
            thread::sleep(Duration::from_millis(100));
        }
    });
    
    for i in 1..3 {
        println!("메인에서: {}", i);
        thread::sleep(Duration::from_millis(100));
    }
    
    handle.join().unwrap();
    println!("완료!");
}
중급2024-01-14

패턴 매칭 심화

match 표현식의 다양한 패턴 매칭 기법입니다.

#패턴매칭#enum#match
enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    Color(i32, i32, i32),
}

fn process(msg: Message) {
    match msg {
        Message::Quit => println!("종료"),
        Message::Move { x, y } => {
            println!("이동: ({}, {})", x, y)
        }
        Message::Write(text) => println!("메시지: {}", text),
        Message::Color(r, g, b) => {
            println!("색상: RGB({}, {}, {})", r, g, b)
        }
    }
}

fn main() {
    process(Message::Move { x: 10, y: 20 });
    process(Message::Write("안녕!".to_string()));
}
초급2024-01-13

파일 읽기/쓰기

파일 시스템 작업의 기본적인 방법입니다.

#파일#IO#시스템
use std::fs::File;
use std::io::{self, Read, Write};

fn main() -> io::Result<()> {
    // 파일 쓰기
    let mut file = File::create("hello.txt")?;
    file.write_all(b"Hello, Rust!")?;
    
    // 파일 읽기
    let mut file = File::open("hello.txt")?;
    let mut contents = String::new();
    file.read_to_string(&mut contents)?;
    
    println!("파일 내용: {}", contents);
    Ok(())
}
중급2024-01-12

Box와 스마트 포인터

Box를 사용한 힙 할당과 재귀 타입 정의입니다.

#Box#스마트포인터#힙
// 재귀적 타입 정의
enum List {
    Cons(i32, Box<List>),
    Nil,
}

use List::{Cons, Nil};

fn main() {
    // Box로 힙에 할당
    let b = Box::new(5);
    println!("b = {}", b);
    
    // 연결 리스트 생성
    let list = Cons(1, 
        Box::new(Cons(2, 
            Box::new(Cons(3, 
                Box::new(Nil))))));
    
    print_list(&list);
}

fn print_list(list: &List) {
    match list {
        Cons(val, next) => {
            print!("{} -> ", val);
            print_list(next);
        }
        Nil => println!("Nil"),
    }
}
고급2024-01-11

매크로 기초

선언적 매크로를 정의하고 사용하는 방법입니다.

#매크로#메타프로그래밍#고급
// 간단한 매크로 정의
macro_rules! say_hello {
    () => {
        println!("Hello!");
    };
    ($name:expr) => {
        println!("Hello, {}!", $name);
    };
}

// vec! 스타일 매크로
macro_rules! my_vec {
    ( $( $x:expr ),* ) => {
        {
            let mut temp_vec = Vec::new();
            $(
                temp_vec.push($x);
            )*
            temp_vec
        }
    };
}

fn main() {
    say_hello!();
    say_hello!("Rust");
    
    let v = my_vec![1, 2, 3, 4, 5];
    println!("벡터: {:?}", v);
}
macro_wizard
103
612
35
중급2024-01-10

Iterator 체이닝

여러 Iterator 메서드를 체이닝하여 데이터를 처리합니다.

#iterator#함수형#체이닝
fn main() {
    let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    
    // 짝수만 필터링하고 제곱한 후 합계
    let result: i32 = numbers
        .iter()
        .filter(|&n| n % 2 == 0)
        .map(|n| n * n)
        .sum();
    
    println!("짝수 제곱의 합: {}", result);
    
    // take, skip 활용
    let partial: Vec<&i32> = numbers
        .iter()
        .skip(2)
        .take(5)
        .collect();
    
    println!("부분 배열: {:?}", partial);
    
    // enumerate 활용
    for (idx, val) in numbers.iter().enumerate() {
        println!("[{}] = {}", idx, val);
    }
}