Scoping rules(오너쉽, 참조, 라이프타임)
Scoping rules - ownership 과 borrowing 그리고 lifetimes 에서 중요한 역할을 한다.
part 1 - RAII (Resource Acquistion Is Initialization)
러스트에서 변수는 데이터를 스택에 저장하는 것만 하는 것은 아니다. --> 리소스를 소유하고 있다.
예로 Box
이러한 행위는 리소스 누수 버그를 예방하고 수동적으로 메모리를 없앨 필요가 없다. 예제를 통해 살펴보자.
fn create_box() { // Allocate an integer on the heap, 힙에 지정 i32 type let _box1 = Box::new(3i32); // `_box1` is destroyed here, and memory gets freed, scope 가 끝나는 시점에서 메모리에서 없어짐. } fn main() { // Allocate an integer on the heap, 힙에 i32 타입 지정 let _box2 = Box::new(5i32); // A nested scope: scope 만들기. { // Allocate an integer on the heap, scope 안에서 힙에 i32 타입 지정 let _box3 = Box::new(4i32); // `_box3` is destroyed here, and memory gets freed, scope 끝나는 시점에서 destructor 호출 -> drop } // Creating lots of boxes just for fun // There's no need to manually free memory!, //1000 개를 힙에 저장시키지만 단 한 개도 남지 않는다. for _ in 0u32..1_000 { create_box(); } // `_box2` is destroyed here. }
part 2 Destructor
스코프를 벗어날 때 호출되는 destructor 는 러스트가 제공하는 Drop
trait 에 의해 실행된다.
자동으로 실행되며 따로 코드를 impl 할 필요는 없지만 필요하다면 구현할 수도 있다.
변수가 scope 를 벗어나려는 순간, destructor 는 호출되며 drop 이 실행된다.
// part 2 struct ToDrop; impl Drop for ToDrop { fn drop(&mut self) { println!("이 객체는 dropped 된다."); } } fn main() { let x = ToDrop; println!("곧 드랍될 예정"); }