Rust의 고급 기능들을 마스터하면 더 유연하고 재사용 가능한 코드를 작성할 수 있습니다. 이 장에서는 제네릭, 트레이트, 스마트 포인터, 클로저, 이터레이터 등을 심도 있게 다룹니다.
제네릭을 사용하면 여러 타입에서 작동하는 코드를 한 번만 작성할 수 있습니다. 코드 중복을 줄이고 타입 안전성을 유지합니다.
// 제네릭 없이 - 코드 중복
fn largest_i32(list: &[i32]) -> &i32 {
let mut largest = &list[0];
for item in list {
if item > largest {
largest = item;
}
}
largest
}
fn largest_char(list: &[char]) -> &char {
let mut largest = &list[0];
for item in list {
if item > largest {
largest = item;
}
}
largest
}
// 제네릭 사용 - 한 번만 작성
fn largest<T: PartialOrd>(list: &[T]) -> &T {
let mut largest = &list[0];
for item in list {
if item > largest {
largest = item;
}
}
largest
}
fn main() {
let numbers = vec![34, 50, 25, 100, 65];
let result = largest(&numbers);
println!("가장 큰 수: {}", result);
let chars = vec!['y', 'm', 'a', 'q'];
let result = largest(&chars);
println!("가장 큰 문자: {}", result);
}
// 하나의 타입 매개변수
struct Point<T> {
x: T,
y: T,
}
impl<T> Point<T> {
fn x(&self) -> &T {
&self.x
}
}
fn main() {
let integer = Point { x: 5, y: 10 };
let float = Point { x: 1.0, y: 4.0 };
// let wont_work = Point { x: 5, y: 4.0 }; // 에러! 타입이 달라야 함
}
// 여러 타입 매개변수
struct Point2D<T, U> {
x: T,
y: U,
}
fn main() {
let both_integer = Point2D { x: 5, y: 10 };
let both_float = Point2D { x: 1.0, y: 4.0 };
let integer_and_float = Point2D { x: 5, y: 4.0 }; // OK!
}
// Option과 Result는 제네릭 열거형
enum Option<T> {
Some(T),
None,
}
enum Result<T, E> {
Ok(T),
Err(E),
}
// 커스텀 제네릭 열거형
enum Data<T> {
Single(T),
Multiple(Vec<T>),
None,
}
fn main() {
let single = Data::Single(42);
let multiple = Data::Multiple(vec![1, 2, 3]);
let none: Data<i32> = Data::None;
}
struct Point<T> {
x: T,
y: T,
}
impl<T> Point<T> {
fn new(x: T, y: T) -> Self {
Point { x, y }
}
}
// 특정 타입에만 메서드 구현
impl Point<f32> {
fn distance_from_origin(&self) -> f32 {
(self.x.powi(2) + self.y.powi(2)).sqrt()
}
}
fn main() {
let p1 = Point::new(5, 10);
let p2 = Point::new(1.0, 4.0);
// p1.distance_from_origin(); // 에러! i32 타입에는 이 메서드 없음
println!("거리: {}", p2.distance_from_origin()); // OK!
}
Rust는 컴파일 시 단형화(monomorphization)를 수행합니다. 제네릭 코드를 사용하는 각 구체 타입에 대해 별도의 코드를 생성하므로, 제네릭 사용에 런타임 비용이 없습니다!
트레이트는 특정 타입이 가지고 있는 기능을 다른 타입과 공유할 수 있게 해줍니다. 다른 언어의 인터페이스와 비슷하지만 더 강력합니다.
pub trait Summary {
fn summarize(&self) -> String;
}
pub struct NewsArticle {
pub headline: String,
pub location: String,
pub author: String,
pub content: String,
}
impl Summary for NewsArticle {
fn summarize(&self) -> String {
format!("{}, by {} ({})", self.headline, self.author, self.location)
}
}
pub struct Tweet {
pub username: String,
pub content: String,
pub reply: bool,
pub retweet: bool,
}
impl Summary for Tweet {
fn summarize(&self) -> String {
format!("{}: {}", self.username, self.content)
}
}
fn main() {
let article = NewsArticle {
headline: String::from("Rust 1.0 출시!"),
location: String::from("서울"),
author: String::from("김러스트"),
content: String::from("안전하고 빠른 시스템 프로그래밍 언어..."),
};
let tweet = Tweet {
username: String::from("@rustacean"),
content: String::from("Rust 배우는 중! #rust"),
reply: false,
retweet: false,
};
println!("기사: {}", article.summarize());
println!("트윗: {}", tweet.summarize());
}
pub trait Summary {
fn summarize_author(&self) -> String;
// 기본 구현
fn summarize(&self) -> String {
format!("({}님의 글 더 읽기...)", self.summarize_author())
}
}
impl Summary for Tweet {
fn summarize_author(&self) -> String {
format!("@{}", self.username)
}
// summarize는 기본 구현 사용
}
fn main() {
let tweet = Tweet {
username: String::from("rustacean"),
content: String::from("물론 Rust는 최고!"),
reply: false,
retweet: false,
};
println!("1개의 새 트윗: {}", tweet.summarize());
}
제네릭 타입이 특정 트레이트를 구현하도록 제한합니다.
// 트레이트 바운드 - 긴 형식
pub fn notify<T: Summary>(item: &T) {
println!("속보! {}", item.summarize());
}
// impl Trait 문법 - 짧은 형식
pub fn notify(item: &impl Summary) {
println!("속보! {}", item.summarize());
}
// 여러 트레이트 바운드
pub fn notify<T: Summary + Display>(item: &T) {
// T는 Summary와 Display 모두 구현해야 함
}
// where 절 - 복잡한 경우 더 읽기 쉬움
fn some_function<T, U>(t: &T, u: &U) -> i32
where
T: Display + Clone,
U: Clone + Debug,
{
// ...
}
// impl Trait을 반환 타입으로 사용
fn returns_summarizable() -> impl Summary {
Tweet {
username: String::from("rustacean"),
content: String::from("Rust는 훌륭해!"),
reply: false,
retweet: false,
}
}
// 주의: 여러 타입을 반환할 수 없음
// fn returns_summarizable(switch: bool) -> impl Summary {
// if switch {
// NewsArticle { ... } // 에러!
// } else {
// Tweet { ... }
// }
// }
use std::fmt::Display;
struct Pair<T> {
x: T,
y: T,
}
impl<T> Pair<T> {
fn new(x: T, y: T) -> Self {
Self { x, y }
}
}
// Display를 구현한 타입에만 cmp_display 메서드 제공
impl<T: Display + PartialOrd> Pair<T> {
fn cmp_display(&self) {
if self.x >= self.y {
println!("가장 큰 멤버는 x = {}", self.x);
} else {
println!("가장 큰 멤버는 y = {}", self.y);
}
}
}
Clone: 값을 명시적으로 복제Copy: 값을 암시적으로 복사 (스택 전용)Debug: {:?} 포맷팅Display: {} 포맷팅PartialEq, Eq: 동등성 비교PartialOrd, Ord: 순서 비교Iterator: 이터레이션 가능스마트 포인터는 포인터처럼 동작하지만 추가 메타데이터와 기능을 가진 데이터 구조입니다.
fn main() {
// 값을 힙에 저장
let b = Box::new(5);
println!("b = {}", b);
// 재귀 타입 정의에 필수
enum List {
Cons(i32, Box<List>),
Nil,
}
use List::{Cons, Nil};
let list = Cons(1,
Box::new(Cons(2,
Box::new(Cons(3,
Box::new(Nil))))));
}
여러 소유자가 하나의 데이터를 공유할 때 사용합니다.
use std::rc::Rc;
enum List {
Cons(i32, Rc<List>),
Nil,
}
use List::{Cons, Nil};
fn main() {
let a = Rc::new(Cons(5, Rc::new(Cons(10, Rc::new(Nil)))));
println!("a 생성 후 카운트 = {}", Rc::strong_count(&a));
let b = Cons(3, Rc::clone(&a));
println!("b 생성 후 카운트 = {}", Rc::strong_count(&a));
{
let c = Cons(4, Rc::clone(&a));
println!("c 생성 후 카운트 = {}", Rc::strong_count(&a));
}
println!("c가 스코프를 벗어난 후 카운트 = {}", Rc::strong_count(&a));
}
불변 참조로도 내부 값을 변경할 수 있게 해줍니다. 런타임에 빌림 규칙을 확인합니다.
use std::cell::RefCell;
fn main() {
let data = RefCell::new(5);
// 불변 참조
let value = data.borrow();
println!("값: {}", value);
drop(value); // 명시적으로 해제
// 가변 참조
*data.borrow_mut() += 1;
println!("변경된 값: {}", data.borrow());
}
// 실제 사용 예: 목(mock) 객체
pub trait Messenger {
fn send(&self, msg: &str);
}
pub struct MockMessenger {
sent_messages: RefCell<Vec<String>>,
}
impl MockMessenger {
pub fn new() -> MockMessenger {
MockMessenger {
sent_messages: RefCell::new(vec![]),
}
}
}
impl Messenger for MockMessenger {
fn send(&self, message: &str) {
// self가 불변이지만 내부 값 변경 가능!
self.sent_messages.borrow_mut().push(String::from(message));
}
}
use std::rc::Rc;
use std::cell::RefCell;
#[derive(Debug)]
enum List {
Cons(Rc<RefCell<i32>>, Rc<List>),
Nil,
}
use List::{Cons, Nil};
fn main() {
let value = Rc::new(RefCell::new(5));
let a = Rc::new(Cons(Rc::clone(&value), Rc::new(Nil)));
let b = Cons(Rc::new(RefCell::new(3)), Rc::clone(&a));
let c = Cons(Rc::new(RefCell::new(4)), Rc::clone(&a));
*value.borrow_mut() += 10;
println!("a = {:?}", a);
println!("b = {:?}", b);
println!("c = {:?}", c);
}
Box<T>: 단일 소유자, 힙 할당, 컴파일 타임 확인Rc<T>: 여러 소유자, 불변 데이터, 컴파일 타임 확인RefCell<T>: 단일 소유자, 가변 데이터, 런타임 확인클로저는 변수를 캡처할 수 있는 익명 함수입니다.
fn main() {
let expensive_closure = |num: u32| -> u32 {
println!("계산 중...");
std::thread::sleep(std::time::Duration::from_secs(2));
num
};
println!("결과: {}", expensive_closure(10));
// 타입 추론
let add_one = |x| x + 1;
println!("5 + 1 = {}", add_one(5));
}
fn main() {
let x = 4;
// 불변 빌림으로 캡처
let equal_to_x = |z| z == x;
// let y = x; // 에러! x가 빌려진 상태
println!("equal_to_x(4) = {}", equal_to_x(4));
// 가변 빌림으로 캡처
let mut list = vec![1, 2, 3];
println!("변경 전: {:?}", list);
let mut borrows_mutably = || list.push(7);
borrows_mutably();
println!("변경 후: {:?}", list);
// 소유권 이동
let list2 = vec![1, 2, 3];
let takes_ownership = move || {
println!("클로저에서: {:?}", list2);
};
// println!("{:?}", list2); // 에러! list2가 이동됨
takes_ownership();
}
// FnOnce: 한 번만 호출 가능 (소유권 이동)
// FnMut: 여러 번 호출 가능, 환경 변경 가능
// Fn: 여러 번 호출 가능, 환경 변경 불가
fn call_with_different_values<F>(f: F)
where
F: Fn(i32) -> i32,
{
println!("f(1) = {}", f(1));
println!("f(2) = {}", f(2));
}
fn main() {
let double = |x| x * 2;
call_with_different_values(double);
}
이터레이터는 값들의 시퀀스를 처리하는 방법을 제공합니다.
fn main() {
let v1 = vec![1, 2, 3];
// iter() - 불변 참조
let v1_iter = v1.iter();
for val in v1_iter {
println!("값: {}", val);
}
// into_iter() - 소유권 이동
for val in v1.into_iter() {
println!("소유한 값: {}", val);
}
// println!("{:?}", v1); // 에러! v1이 이동됨
let mut v2 = vec![1, 2, 3];
// iter_mut() - 가변 참조
for val in v2.iter_mut() {
*val += 10;
}
println!("{:?}", v2); // [11, 12, 13]
}
fn main() {
let v = vec![1, 2, 3, 4, 5];
// map - 각 요소 변환
let doubled: Vec<_> = v.iter().map(|x| x * 2).collect();
println!("2배: {:?}", doubled);
// filter - 조건에 맞는 요소만
let evens: Vec<_> = v.iter().filter(|x| *x % 2 == 0).collect();
println!("짝수: {:?}", evens);
// 체이닝
let result: Vec<_> = v.iter()
.filter(|x| **x > 2)
.map(|x| x * 2)
.collect();
println!("2보다 크고 2배: {:?}", result);
}
fn main() {
let v = vec![1, 2, 3, 4, 5];
// sum - 합계
let sum: i32 = v.iter().sum();
println!("합계: {}", sum);
// any - 하나라도 조건 만족?
let has_even = v.iter().any(|x| x % 2 == 0);
println!("짝수 있음? {}", has_even);
// all - 모두 조건 만족?
let all_positive = v.iter().all(|x| *x > 0);
println!("모두 양수? {}", all_positive);
// find - 첫 번째 매칭 요소
let first_even = v.iter().find(|x| *x % 2 == 0);
println!("첫 짝수: {:?}", first_even);
// enumerate - 인덱스와 함께
for (i, val) in v.iter().enumerate() {
println!("v[{}] = {}", i, val);
}
// zip - 두 이터레이터 결합
let names = vec!["Alice", "Bob", "Carol"];
let scores = vec![90, 85, 95];
for (name, score) in names.iter().zip(scores.iter()) {
println!("{}: {}", name, score);
}
}
struct Counter {
count: u32,
}
impl Counter {
fn new() -> Counter {
Counter { count: 0 }
}
}
impl Iterator for Counter {
type Item = u32;
fn next(&mut self) -> Option<Self::Item> {
if self.count < 5 {
self.count += 1;
Some(self.count)
} else {
None
}
}
}
fn main() {
let counter = Counter::new();
for num in counter {
println!("{}", num); // 1, 2, 3, 4, 5
}
// Iterator 트레이트의 다른 메서드 사용 가능
let sum: u32 = Counter::new()
.zip(Counter::new().skip(1))
.map(|(a, b)| a * b)
.filter(|x| x % 3 == 0)
.sum();
println!("합계: {}", sum);
}
이터레이터는 종종 루프보다 빠릅니다! Rust 컴파일러가 이터레이터를 최적화하여 zero-cost abstraction을 실현합니다.
use std::rc::Rc;
use std::cell::RefCell;
// WIA-AI-CITY 메모리 관리 시스템
trait MemoryAllocator {
fn allocate(&mut self, size: usize) -> Result<usize, String>;
fn deallocate(&mut self, ptr: usize);
}
struct HBMAllocator {
total: usize,
used: usize,
blocks: RefCell<Vec<(usize, usize)>>, // (ptr, size)
}
impl HBMAllocator {
fn new(total_gb: usize) -> Self {
HBMAllocator {
total: total_gb * 1024 * 1024 * 1024,
used: 0,
blocks: RefCell::new(Vec::new()),
}
}
fn usage_percent(&self) -> f64 {
(self.used as f64 / self.total as f64) * 100.0
}
}
impl MemoryAllocator for HBMAllocator {
fn allocate(&mut self, size: usize) -> Result<usize, String> {
if self.used + size > self.total {
return Err("HBM 용량 초과".to_string());
}
let ptr = self.used;
self.used += size;
self.blocks.borrow_mut().push((ptr, size));
Ok(ptr)
}
fn deallocate(&mut self, ptr: usize) {
let mut blocks = self.blocks.borrow_mut();
if let Some(pos) = blocks.iter().position(|(p, _)| *p == ptr) {
let (_, size) = blocks.remove(pos);
self.used -= size;
}
}
}
fn main() {
let mut hbm = HBMAllocator::new(80); // 80GB HBM
match hbm.allocate(1024 * 1024 * 1024) {
Ok(ptr) => println!("할당됨: 포인터 {}, 사용률: {:.2}%",
ptr, hbm.usage_percent()),
Err(e) => println!("할당 실패: {}", e),
}
}
clone() 대신 참조 사용한국 일반 인프라 — 과기정통부(MSIT)·행정안전부(MOIS)·KISA·KCMVP·NIS·NIA·TTA·KATS·KOLAS·ETRI·KAIST·KIST·KISTI·POSTECH·서울대·연세대·고려대·삼성·LG·SK·KT·LG U+·NAVER·카카오 협력 표준화 작업반 운영 중. 「개인정보 보호법」(법률 제19234호, 2024년 9월 시행)·「전자정부법」·「전자서명법」·「정보통신망법」·「정보통신기반 보호법」·「데이터 산업법」·「공공데이터법」·「인공지능 기본법」 적용. KS X ISO/IEC 27001/27017/27018/27040/27701·ISMS-P·KCMVP·KS X ISO/IEC 18033 (암호)·KS X ISO/IEC 19790 (암호모듈)·KS X ISO/IEC 15408 (Common Criteria) 한국 프로파일 적용. NIA「ICT 표준화 추진체계 운영」·KISA「개인정보보호 종합 포털」·MSIT「K-디지털 2030」 로드맵 운영 중.
한국의 산업·기술 표준화는 다음 협력 체계를 통해 운영된다. 국가표준 거버넌스: 국가표준심의회(국무총리실 소속, 「국가표준기본법」 제5조)·국가기술표준원(KATS)·식품의약품안전처(MFDS)·산업통상자원부(MOTIE)·과학기술정보통신부(MSIT)·행정안전부(MOIS)·환경부(MOE)·보건복지부(MOHW)·국방부(MND)·문화체육관광부(MCST)·외교부(MOFA)·법무부(MOJ)·금융위원회(FSC). 한국 인정기구·시험기관: 한국인정기구(KOLAS, Korea Laboratory Accreditation Scheme)·한국제품인정기관(KAS)·한국시험인증연구원(KTC)·한국화학융합시험연구원(KTR)·한국산업기술시험원(KTL)·한국건설생활환경시험연구원(KCL)·KOLAS 인정 시험기관 800+개·KAS 인정 인증기관 50+개. 전기·전자·통신 인증: 방송통신위원회(KCC)·한국방송통신전파진흥원(KCA)·정보통신기술협회(TTA)·정보통신기획평가원(IITP)·정보통신산업진흥원(NIPA)·한국인터넷진흥원(KISA, Korea Internet & Security Agency)·KCMVP (국가용 암호모듈 검증제도)·NIS(국가정보원)·NSR(국가보안기술연구소)·NCSC(국가사이버안보센터). 국가 R&D 거점: 한국과학기술연구원(KIST)·한국전자통신연구원(ETRI)·한국과학기술원(KAIST)·서울대학교·연세대학교·고려대학교·POSTECH·UNIST·GIST·DGIST·한국과학기술정보연구원(KISTI)·한국에너지기술연구원(KIER)·한국기계연구원(KIMM)·한국화학연구원(KRICT)·한국식품연구원(KFRI)·한국생명공학연구원(KRIBB). 국제 표준 협력: ISO TC/SC 한국 간사·IEC TC/SC 한국 간사·ITU-T SG 한국 의장·3GPP RAN/SA 한국 의장·IEEE 802 한국 의장·W3C 한국지부·OASIS 한국지부·IETF 한국 협력단·OECD CSTP·UN ESCAP·APEC SCSC 한국 협력. 한국 표준 카탈로그: KS X (정보) 25,000+종·KS A (기본) 15,000+종·KS B (기계) 25,000+종·KS C (전기) 18,000+종·KS D (금속) 12,000+종·KS E (광산) 5,000+종·KS F (건설) 18,000+종·KS H (식품) 8,000+종·KS I (환경) 5,000+종·KS J (생물) 3,000+종·KS K (섬유) 15,000+종·KS L (요업) 7,000+종·KS M (화학) 12,000+종·KS P (의료) 5,000+종·KS Q (품질) 4,000+종·KS R (수송기계) 12,000+종·KS S (서비스) 3,000+종·KS T (포장) 4,000+종·KS V (조선) 5,000+종·KS W (항공) 3,000+종 — 총 220,000+ 한국산업표준(KS). 「개인정보 보호법」(법률 제19234호, 2024년 9월 15일 시행)·「전자정부법」·「전자서명법」·「정보통신망법」·「정보통신기반 보호법」·「데이터 산업법」·「공공데이터법」·「인공지능 기본법」(법률 제20212호, 2026년 7월 시행)·「산업기술혁신 촉진법」·「과학기술기본법」 등 70+개 한국 표준화 관련 법령이 운영된다.
한국의 디지털 전환과 표준화는 다음 협력 체계로 운영된다. 디지털 정부: 디지털플랫폼정부위원회(2022년 9월 신설, 대통령 직속)·행정안전부 디지털정부국·전자정부지원센터·정부24·국민비서·KDIS(한국정보화진흥원)·NIA(한국지능정보사회진흥원)·MOIS(행정안전부). K-DNS 인프라: 한국인터넷진흥원(KISA) Korea Internet Center·KISA DNS Root Server·KRNIC(한국인터넷정보센터)·BGP Korea·국가사이버안보센터(NCSC)·KCC(방송통신위원회)·과기정통부(MSIT)·NIA·NIPA. 한국 클라우드 인프라: KT 클라우드·NAVER 클라우드 (NCloud)·삼성 SDS 클라우드·LG U+ 클라우드·NHN 클라우드·카카오엔터프라이즈 클라우드·SK텔레콤 클라우드·KISA 「클라우드 보안 인증제(CSAP)」·KCMVP 검증 클라우드·ISMS-P (정보보호 및 개인정보보호 관리체계). 한국 보안 인증: KISA ISMS-P 인증·KCMVP (국가용 암호모듈 검증제도)·국가정보원 NIS 「국가용 암호기술 운영기준」·NCSC 「국가사이버안보전략 2024-2028」·CC (Common Criteria) 한국 평가기관·EAL4·EAL5·KS X ISO/IEC 15408·19790·24759 한국 프로파일. 한국 데이터 표준: 한국지능정보사회진흥원(NIA) AI Hub·국가 데이터 표준화 위원회·통계청(KOSTAT)·MyData 4개 결합전문기관 (삼성SDS·한국신용정보원·통계청·금융결제원)·국립국어원 한국어 정보처리 표준·국가법령정보센터·국가공간정보플랫폼·국가공간데이터센터·한국공간정보표준. 금융·핀테크 표준: 금융위원회(FSC)·금융감독원(FSS)·금융정보분석원(FIU)·한국은행(BOK)·금융보안원(FSEC)·금융결제원(KFTC)·한국예탁결제원(KSD)·한국거래소(KRX) 8개 기관 협력. 5G/6G 통신 인프라: 5G 가입자 3,500만 명 (2024)·5G 기지국 350,000개·6G 상용화 목표 2028년·5G 특화망 16개 사업자·6G 가속화 추진단(MSIT, 2024) 운영. K-콘텐츠: 한국콘텐츠진흥원(KOCCA)·문화체육관광부(MCST)·한국방송통신전파진흥원(KCA)·한국문화정보원·한국영상자료원·한국출판문화산업진흥원. 「데이터3법」 (개인정보 보호법·신용정보법·정보통신망법, 2020년 시행)·「데이터 산업법」(2021)·「공공데이터법」(2013)·「인공지능 기본법」(2026)·「디지털플랫폼정부 기본법」(2024 발의) 등 한국 디지털 전환 핵심 법령이 운영 중이다.