STUDY/Rust

Rust - 18. 스마트 포인터 (1) Box<T>, Deref, Drop

sinawi95 2024. 3. 21. 21:12
728x90

또 포인터야? 오늘도 포인터 때문에 이해안돼서 애먹었는데..?


포인터(pointer): 메모리의 주솟값을 담고 있는 변수에 대한 일반적인 개념

스마트 포인터(smart pointer): 포인터 + 추가적인 메타데이터와 능력

  • C++에서 유래됨. 이해하기 어려우면 C++에서 먼저 이해하고 오자

 

1. Box<T>

Box<T>

  • 힙에 데이터 저장
  • 스택과 비교해서 힙에 저장하는것 제외하면 성능 측면에서 오버헤드 없음

사용하는 이유(이해 못함)

  • 컴파일 타임에는 크기를 알 수 없는 타입이 있는데, 정확한 크기를 요구하는 컨텍스트 내에서 그 타입의 값을 사용하고 싶을 때
    • 재귀적 타입을 사용하면 공간의 크기를 알기 어려움.
    • Box<T>인 포인터로 대체하면 크기가 고정되므로 사용할수 있음
  • 커다란 데이터를 가지고 있고 소유권을 옮기고 싶지만 그렇게 했을 때 데이터가 복사되지 않을 것을 보장하고 싶을 때
    • 스택에 포인터 데이터만 복사하고 다량의 데이터는 힙에 두고 사용
  • 어떤 값을 소유하고 이 값의 구체화된 타입보다는 특정 트레이트를 구현한 타입이라는 점만 신경 쓰고 싶을 때
    • 트레이트 객체

예시

fn main() {
    let b = Box::new(5);
    println!("b = {}", b);
}
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))))));
}

 

2. Deref 트레이트, 스마트 포인터를 보통참조자처럼 취급하기

Deref 트레이트

  • 역참조 연산자 *(dereference operator) 동작을 커스터마이징 할 수 있음.
use std::ops::Deref;

impl<T> Deref for MyBox<T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

struct MyBox<T>(T);

impl<T> MyBox<T> {
    fn new(x: T) -> MyBox<T> {
        MyBox(x)
    }
}

fn main() {
    let x = 5;
    let y = MyBox::new(x);

    assert_eq!(5, x);
    assert_eq!(5, *y); //역참조
}

Deref coercion 역참조 강제

  • 어떤 타입의 참조자를 다른 타입의 참조자로 변경
  • 명시적인 참조, 역참조를 추가할 필요가 없도록 하기위해 도입됨

역참조 강제가 가변성과 상호작용하는 법

  • T: Deref<Target=U>일 때 &T에서 &U로
  • T: DerefMut<Target=U>일 때 &mut T에서 &mut U로
  • T: Deref<Target=U>일 때 &mut T에서 &U로

 

3. Drop 트레이트

Drop: 메모리 정리 코드 실행

  • 값이 스코프 밖으로 벗어날때마다 실행되는 코드
  • 버려지는 순서는 만들어진 순서의 역순으로 진행됨

std::mem::drop

  • Drop 트레이트가 실행되기 전에 먼저 정리 하고 싶은 경우 사용
  • 두 번 정리하는 것을 막음

https://doc.rust-kr.org/ch15-00-smart-pointers.html

 

'STUDY > Rust' 카테고리의 다른 글

Rust - 20. 동시성, 병렬성  (1) 2024.03.24
Rust - 19. 스마트 포인터 (2) Rc<T>, RefCell<T>, 순환 참조  (1) 2024.03.23
Rust - 17. Cargo와 Crates.io  (0) 2024.03.19
Rust - 16. 반복자  (0) 2024.03.14
Rust - 15. 클로저  (0) 2024.03.11