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

RefCell & 내부 가변성

~12 min · smart-pointers, refcell, interior-mutability

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

Rc 는 공유 소유권을 주지만 불변 접근만. RefCell<T> 가 빠진 절반을 줘: borrow 검사를 컴파일 타임에서 런타임 으로 옮겨, 공유 참조로 변형하는 능력. 이게 내부 가변성 이야.

런타임에 검사되는 borrow 규칙

보통 borrow checker 는 aliasing XOR mutation 을 컴파일 타임에 강제해. RefCell 은 대신 런타임 검사로 옵트인하게 해: .borrow() 는 공유 참조를, .borrow_mut() 은 가변을 주고, 런타임에 추적해. 규칙을 어기면 — 가변 borrow 둘 동시 — 컴파일 실패 대신 panic 해. 같은 보장, 나중에 강제.

왜 검사를 런타임으로 옮기냐?

어떤 유효한 패턴은 컴파일 타임에 안전을 증명 못 해 — 공유 구조로 변형되는 값, 테스트에서 호출을 쌓는 mock 객체, 다른 데서 갱신되는 그래프 노드. RefCell 은 '믿어, borrow 규칙 지킬게; 런타임에 검사해' 라고 말해. 컴파일 타임 보장을 유연성과 맞바꿔, 규칙을 어기면 panic 날 수 있음을 받아들이고.

RefCell 은 borrow 에러를 컴파일 타임에서 런타임으로 옮겨. 안전은 같아 — aliasing XOR mutation 은 여전히 성립 — 근데 위반이 컴파일 실패 대신 런타임에 panic 해. 컴파일 타임 검사기를 진짜 만족 못 할 때만 써; 먼저 보통 참조로 손 뻗어.

Rc + RefCell: 공유 & 가변

전형적 콤보는 Rc<RefCell<T>> 야: 여러 owner 엔 Rc, 공유 값 변형엔 RefCell. 노드를 갱신할 수 있는 트리나 단일 스레드 코드의 공유 가변 상태를 짓는 법이야. (멀티스레드 코드에선 동등물이 Arc<Mutex<T>> — 정확한 평행을 새겨.)

Code

Rc<RefCell<T>>: 공유 & 가변·rust
use std::cell::RefCell;
use std::rc::Rc;

fn main() {
    // 공유 AND 가변: owner 엔 Rc, 변형엔 RefCell
    let shared = Rc::new(RefCell::new(vec![1, 2, 3]));

    let a = Rc::clone(&shared);
    a.borrow_mut().push(4); // 공유 핸들로 변형

    println!("{:?}", shared.borrow()); // [1, 2, 3, 4]

    // borrow 규칙 위반은 컴파일 타임이 아니라 런타임에 panic:
    // let _b1 = shared.borrow_mut();
    // let _b2 = shared.borrow_mut(); // panic: 이미 가변으로 빌려짐
}

External links

Exercise

두 핸들이 공유하는 Rc<RefCell<Vec<String>>> 로그를 지어. 각 핸들로 메시지를 push 하고, 세 번째 clone 으로 합쳐진 로그를 읽어. 그다음 일부러 borrow_mut() 둘을 동시에 살려두고 런타임 panic 을 봐. RefCell 은 왜 컴파일 거부 대신 panic 해?
Hint
RefCell 의 목적 전부가 borrow 검사를 런타임으로 미뤄 컴파일 타임 검사기가 증명 못 하는 패턴을 가능하게 하는 거야. 그 유연성의 비용이 위반된 규칙이 컴파일 에러 대신 런타임 panic 으로 드러나는 거야.

Progress

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

댓글 0

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

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