← SEARCHABLE ARCHIVE
Rust · 2026-08-08

Rust from Basics to Mastery — Part 8

Choose your ownership structure with Box, Rc, Arc

INTERACTIVE READING MODE →

The articles written on this blog were created with the goal of teaching. Also, the information in the article may be incorrect, so please be careful.

Most values ​​can be owned only by local variables and collections. When you need to stick to the heap or share among multiple owners, choose a smart pointer that suits your purpose.

Box

enum Node {
    Value(i32, Box<Node>),
    End,
}

let list = Node::Value(
    10,
    Box::new(Node::Value(20, Box::new(Node::End))),
);

For recursive types, the size of the next value cannot be known immediately at compile time. Box places the value on the heap and stores a fixed-size pointer in the current type.

Box is not automatically shared and there is still only one primary owner.

Rc and Arc

use std::rc::Rc;

let data = Rc::new(String::from("ItemTable"));
let ui_data = Rc::clone(&data);
let game_data = Rc::clone(&data);

Rc allows multiple places to own the same value in a single thread. The values ​​are cleaned up when the last Rc disappears.

Sharing across multiple threads requires Arc, which uses atomic reference counting. Rc and Arc do not make their internal values ​​changeable by default.

internal variability

use std::cell::RefCell;
use std::rc::Rc;

let score = Rc::new(RefCell::new(0));
*score.borrow_mut() += 10;

RefCell checks borrowing rules at run time, not compile time. At the same time, if borrowed incorrectly, the program panics, so the compilation check does not disappear.

Change access is usually synchronized between threads using a combination of Arc and Mutex.

If you overlap a lot of smart pointers, it becomes difficult to understand the ownership structure. You must first check the purpose of Box owning the heap, Rc sharing with a single thread, and Arc sharing between threads, and select the simplest type.