[Rust] 스마트포인터 Box, Rc

Box
빡스는 가장 기본적인 스마트 포인터 타입이다.
박스는 값을 동적할당하고, 해당 값이 스코프를 벗어날 경우 자동으로 할당을 해제한다.

c++의 unique_ptr에 해당한다. image

image 구조도 간단하고 사용법도 간단해서, 별건 없다.


Rc
Reference Counting의 약자로, 여러놈이 소유권을 공유할 수 있는 포인터다.
c++의 shared_ptr에 해당한다.


image

image 이렇게 막 복사해서 쓰고 바인딩된 변수가 0이 되면 할당이 해제된다.

근데 이놈은 그 자체로는 심각한 기능적 결함이 존재한다. 읽기용으로는 바로 접근이 안된다는 것이다... image

image rc에는 box에는 있는 deref_mut(가변역참조)가 구현되어있지 않기 때문이다.

get_mut 등의 함수를 쓰면 포인터를 끄집어내는게 가능하긴 하지만,
소유권이 날라가기 때문에 복제된 여러 변수에서 동시에 쓰기 작업을 하는 것은 불가능하다.

이 문제를 해결하고싶다면 RefCell이라는 특수한타입을 겹쳐주면 된다.
이놈은 소유권 규칙을 어느정도 무시할 수 있게 해준다.
RefCell::new로 먼저 값을 생성해주고, 그걸 또 Rc로 덮어주면 된다. image

image 이제 수정이 잘 된다!
borrow_mut는 수정가능한 참조를 반환하는 함수다. borrow는 읽기전용이고.

그리고 이 rc는 싱글스레드 기준으로 구현이 되어있기 때문에, 스레드 간에는 사용하면 안된다.
스레드에 사용하려면 Rc-RefCell 조합 대신 Arc-Mutex 조합을 사용해야한다.

Arc는 Rc와 인터페이스가 동일하고.
Mutex는 lock으로 동기화를 걸고 더불어 Option 타입을 벗겨내야 주소값이 나온다는게 다르다.


참조
https://doc.rust-lang.org/std/boxed/struct.Box.html
https://doc.rust-lang.org/std/rc/struct.Rc.html
https://rinthel.github.io/rust-lang-book-ko/ch15-05-interior-mutability.html