커뮤니티에서 공유된 유용한 Rust 코드 스니펫을 탐색하고 학습하세요.
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);
}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!("상세 모드 활성화");
}
}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(())
}fn main() {
let numbers = vec![1, 2, 3, 4, 5];
let sum: i32 = numbers.iter().sum();
println!("합계: {}", sum);
}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(())
}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),
}
}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);
}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]
}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);
}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());
}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");
}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!("사용자를 찾을 수 없습니다");
}
}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));
}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();
}
}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
}
}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);
}
}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);
}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);
}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),
}
}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);
}
}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),
}
}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);
}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!("완료!");
}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()));
}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(())
}// 재귀적 타입 정의
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"),
}
}// 간단한 매크로 정의
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);
}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);
}
}