rust
에서는 일반적으로 &
symbol을 사용하여 pointer의 종류인 reference를 사용한다. 일반 포인터는 자료를 대여하는 것만 가능한 것에대 반해 smart pointer는 그것을 소유할 수 있으며, 대부분 그렇게 작동한다. String
과 Vec<T>
도 스마트 포인터에 해당된다. Smart pointer는 추가적인 metadata와 capabilities를 가지고 있다. Vec
, String
, Box<T>
등이 해당된다.
pub struct Box<T, A = Global>(_, _)
where
A: Allocator,
T: ?Sized;
T
타입에 대해 heap allocation을 가지는 스마트 pointer
type이다. Box는 값을 동적 할당하고, 해당 값이 스코프를 벗어난 경우 자동으로 할당을 해제한다. Rust는 stack에 데이터를 저장할 때 해당 데이터의 사이즈를 알 수 없으면, 컴파일에러가 난다. trait object나 recursive struct type을 활용할 때 이런 문제가 생길 수 있다.
Box<T>
에서 꺼내는 작업 없이 사용할 수 있다. 그리고 소유권을 가진 일반 변수가 그렇듯이 범위를 벗어나면 메모리가 해제된다.recursive type은 compile time에 그 크기를 알 수 없다. recursive type은 자신과 같은 자료형의 값을 참조하기 때문에 이론적으로 무한히 커질 수 있다. 보편적인 재귀 자료형으로는 ConsList(construction list)가 있다. Cons
enum의 첫 번째 값은 리스트에 사용할 data type, 두 번째 값은 List
enum을 저장하도록 하지만, 이 값에 List
enum을 그대로 넣으면 컴파일러는 크기가 무한해질 수 있음을 인지하고 컴파일을 거부한다. 이를 Box<T>
로 해결할 수 있다.
enum List {
Cons(i32, Box<List>),
Nil,
}
use crate::List::{Cons, Nil};
fn main() {
let list = Cons(1,
Box::new(Cons(2,
Box::new(Cons(3,
Box::new(Nil)
))
))
);
}