C.W.K.
Stream
Lesson 03 of 05 · published

Rc — 공유 소유권

~11 min · smart-pointers, rc, shared-ownership

Level 0Rust 호기심러
0 XP0/80 lessons0/19 achievements
0/100 XP to next level100 XP to go0% complete

Box 는 owner 가 하나야. 근데 가끔 값이 진짜로 여러 owner 가 필요해 — 여러 곳에서 참조되는 노드, 여러 부분이 읽는 공유 설정. Rc<T> (reference counted) 가 그걸 안전하게 해.

카운팅으로 공유 소유권

Rc<T> 는 owner 가 몇인지 카운트를 유지해. Rc::clone 은 데이터를 복사 안 해 — 카운트를 올리고 같은 값으로의 다른 핸들을 건네. 각 owner 가 자기 Rc 를 drop 하면 카운트가 내려가고; 0 이 되면 값이 해제돼. 여러 owner, 정확히 한 번 해제, 다 자동.

Rc::clone 은 싸

Rc::clone(&x) 가 관용적 표기야 (x.clone() 보다) 정확히 '이건 싼 refcount 증가지 깊은 복사가 아니야' 를 신호하니까. 포인터를 복사하고 카운터를 올려 — 그뿐. Rc::clone 을 읽으면 '여기 공유 소유권' 이라고 읽는 사람한테 말해줘, 맨 .clone() 은 가릴 걸.

Rc 는 단일 스레드의 여러 owner 용이야. 프로그램 여러 부분이 필요해서 한 값이 어느 단일 owner 보다 오래 살아야 할 때 써. 카운트가 걔들을 추적하고; 마지막 하나가 값을 해제해. (스레드 간 공유는 Arc 가 필요해 — 두 레슨 뒤에.)

함정: Rc 는 읽기 전용

Rc<T> 는 공유 불변 접근을 줘. 그걸 통해 &mut 를 못 얻어, 여러 owner 더하기 변형은 aliasing XOR mutation 을 위반하니까. 공유 데이터를 변형하려면 RcRefCell 이랑 짝지어 — 바로 다음 레슨이고, 내부 가변성이 존재하는 이유야.

Code

Rc: 여러 owner, 한 번 해제·rust
use std::rc::Rc;

struct Config { name: String }

fn main() {
    let shared = Rc::new(Config { name: "app".into() });
    println!("owners: {}", Rc::strong_count(&shared)); // 1

    let a = Rc::clone(&shared); // 싸: 카운트 올리고, 같은 바탕 데이터
    let b = Rc::clone(&shared);
    println!("owners: {}", Rc::strong_count(&shared)); // 3
    println!("{} {}", a.name, b.name);
} // a, b, shared 다 drop -> 카운트 0 도달 -> Config 한 번 해제

External links

Exercise

Rc 로 하나의 Resource 를 공유하는 Owner 둘을 모델링해. 각 clone 후랑 owner drop 후 (안쪽 스코프로 일찍 drop) Rc::strong_count 를 출력해. 카운트가 오르고 내리는 걸 확인해. 여기서 Rc::clone.clone() 보다 스타일상 왜 선호돼?
Hint
Rc::clone 은 데이터를 깊은 복사하는 게 아니라 소유권을 싸게 공유한다는 걸 (refcount 증가) 명시해. .clone() 은 컴파일되지만 의도를 흐려 — 읽는 사람이 싼 Rc clone 을 비싼 깊은 clone 과 구분 못 해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.