
프로그래밍 언어
Rust Ownership SystemRust 소유권 시스템
Rust의 소유권(Ownership) 시스템은 가비지 컬렉터 없이 메모리 안전성을 컴파일 타임에 보장하는 독창적인 메커니즘이다. 소유권, 빌림(Borrowing), 생명주기(Lifetime) 세 가지 규칙으로 구성된다.
소유권 규칙
1. 모든 값에는 정확히 하나의 소유자(owner)가 있다
2. 소유자가 스코프를 벗어나면 값이 해제된다 (drop)
3. 값은 한 번에 하나의 소유자만 가질 수 있다이동(Move)과 복사(Copy)
rust
fn main() {
// String: 힙 할당 → 이동 (move)
let s1 = String::from("hello");
let s2 = s1; // s1의 소유권이 s2로 이동
// println!("{}", s1); // 컴파일 오류! s1은 더 이상 유효하지 않음
// i32: 스택 값 → 복사 (Copy 트레이트)
let x = 5;
let y = x;
println!("{} {}", x, y); // OK: 복사됨
// 명시적 복제
let s3 = String::from("world");
let s4 = s3.clone(); // 깊은 복사
println!("{} {}", s3, s4); // OK
}빌림(Borrowing)과 참조
rust
fn calculate_length(s: &String) -> usize { // 불변 참조
s.len()
} // s는 드롭되지 않음 (소유권 없음)
fn change(s: &mut String) { // 가변 참조
s.push_str(" world");
}
fn main() {
let s = String::from("hello");
let len = calculate_length(&s); // 빌림 (소유권 이전 없음)
println!("{}: {}", s, len); // s 여전히 유효
let mut s2 = String::from("hello");
change(&mut s2);
println!("{}", s2); // "hello world"
// 규칙: 가변 참조는 동시에 하나만 (데이터 레이스 방지)
// let r1 = &mut s2;
// let r2 = &mut s2; // 컴파일 오류!
}생명주기(Lifetime)
rust
// 반환 참조의 생명주기 명시
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() { x } else { y }
}
// 구조체의 참조 생명주기
struct ImportantExcerpt<'a> {
part: &'a str, // 구조체보다 part가 오래 살아야 함
}스마트 포인터
rust
use std::rc::Rc;
use std::cell::RefCell;
// Box<T>: 힙 할당
let b = Box::new(5);
// Rc<T>: 참조 카운팅 (단일 스레드)
let a = Rc::new(String::from("hello"));
let b = Rc::clone(&a); // 참조 카운트 증가
// Arc<T>: 원자적 참조 카운팅 (멀티스레드)
use std::sync::Arc;
let arc = Arc::new(5);
// RefCell<T>: 런타임 빌림 검사 (내부 가변성)
let val = RefCell::new(5);
*val.borrow_mut() += 1;
