내부 가변성
내부 가변성 (Interior mutability)
어떤 타입은 값을 여러 곳에서 공유하고 있는데도 그 안의 상태를 바꿔야 할 때가 있어요. Rust에서는 이걸 내부 가변성(interior mutability) 이라는 패턴으로 해결해요. 이 글에서는 그 개념이 왜 필요한지, 그리고 어떤 타입들이 이 패턴을 쓰는지 살펴볼게요.
출처: Rust Reference
본문
어떤 타입이 내부 가변성을 가진다는 건, 그 타입의 내부 상태를 공유 참조(shared reference) 를 통해서도 바꿀 수 있다는 뜻이에요. 보통은 공유 참조가 가리키는 값을 변경하면 안 되는데, 이건 그 평범한 요구에 정면으로 반하는 일이죠.
std::cell::UnsafeCell<T> 타입이 바로 이 요구를 끄는 것을 허용하는 유일한 방법이에요. UnsafeCell<T>가 불변으로(immutably) 별칭(aliased)되어 있더라도, 그 안의 T를 변경하거나 가변 참조를 얻는 것은 여전히 안전해요.
물론 다른 모든 타입과 마찬가지로, &mut UnsafeCell<T> 별칭이 여러 개 존재하면 그건 정의되지 않은 동작(undefined behavior) 이야.
그 밖에 내부 가변성을 가진 타입들은 UnsafeCell<T>를 필드로 사용해서 만들어져요. 표준 라이브러리는 내부 가변성에 대한 안전한 API를 제공하는 다양한 타입들을 포함하고 있죠.
예를 들어 std::cell::RefCell<T>는 런타임 차용 검사(run-time borrow checks)를 사용해서 여러 참조에 관한 평범한 규칙을 보장해요. 즉 컴파일 타임이 아니라 실행 중에 빌려오기 규칙을 지키는 거죠.
std::sync::atomic 모듈에는 값에 원자적 연산(atomic operations) 으로만 접근하게 감싸는 타입들이 있어요. 덕분에 그 값을 스레드 간에 공유하고 변경할 수 있어요.
더 알아보기 (Learn more)
std::cell::UnsafeCell문서 — 내부 가변성의 가장 낮은 수준 기반std::cell모듈 문서 —Cell,RefCell,OnceCell등std::sync::atomic모듈 문서 — 스레드 간 원자적 공유