https://www.tutorialspoint.com/rust/rust_smart_pointers.htm
Rust는 기본적으로 stack에 할당
Box와 같은 스마트 포인터로 래핑하여 힙에 할당 가능
Vec 및 String 같은 형식은 암시적으로 힙에 할당
스마트 포인터는 아래 표에 표시된 trait을 구현
스마트 포인터의 이러한 trait은 일반 structure와 구분
Sr.No. | Trait name | Package | Description |
---|---|---|---|
1 | Deref | std::ops::Deref | *v와 같은 변경할 수 없는 역참조 작업에 사용 |
2 | Drop | std::ops::Drop | 값이 범위를 벗어날 때 일부 코드를 실행하는 데 사용, 소멸자라고도 불림 |
Box 스마트 포인터를 사용하면 스택이 아닌 힙에 데이터를 저장할 수 있음
스택에는 힙 데이터에 대한 포인터가 포함
Box에는 데이터를 힙에 저장하는 것 외에는 성능 오버헤드가 없음
fn main() {
let var_i32 = 5;
//stack
let b = Box::new(var_i32);
//heap
println!("b = {}", b);
}
변수가 가리키는 값에 접근하려면 역참조를 사용
*는 역참조 연산자로 사용
fn main() {
let x = 5;
//value type variable
let y = Box::new(x);
//y points to a new value 5 in the heap
println!("{}",5==x);
println!("{}",5==*y);
//dereferencing y
}
표준 라이브러리에서 제공하는 Deref trait을 사용하려면 자체를 self를 borrow 하고 내부 데이터에 대한 참조를 반환하는 deref라는 메서드를 구현해야 함
use std::ops::Deref;
struct MyBox<T>(T);
impl<T> MyBox<T> {
// Generic structure with static method new
fn new(x:T)-> MyBox<T> {
MyBox(x)
}
}
impl<T> Deref for MyBox<T> {
type Target = T;
fn deref(&self) -> &T {
&self.0 //returns data
}
}
fn main() {
let x = 5;
let y = MyBox::new(x);
// calling static method
println!("5==x is {}",5==x);
println!("5==*y is {}",5==*y);
// dereferencing y
println!("x==*y is {}",x==*y);
//dereferencing y
}
Drop trait에는 drop() 메서드가 포함
이 trait을 구현한 구조체가 범위를 벗어날 때 이 메서드가 호출됨
일부 언어에서 프로그래머는 스마트 포인터의 인스턴스 사용을 마칠 때마다 메모리나 리소스를 해제하기 위해 코드를 호출
Rust에서는 Drop trait을 사용하여 자동 메모리 할당 해제 기능 제공
use std::ops::Deref;
struct MyBox<T>(T);
impl<T> MyBox<T> {
fn new(x:T)->MyBox<T>{
MyBox(x)
}
}
impl<T> Deref for MyBox<T> {
type Target = T;
fn deref(&self) -> &T {
&self.0
}
}
impl<T> Drop for MyBox<T>{
fn drop(&mut self){
println!("dropping MyBox object from memory ");
}
}
fn main() {
let x = 50;
MyBox::new(x);
MyBox::new("Hello");
}