rc
import std::alloc::rc; — in the prelude · source
Types
Rc<T, A>
type struct Rc<T, A = GlobalAlloc> where A: Allocator {
inner: RcInner<T, A>*;
static new(value: T) -> Rc<T, GlobalAlloc>;
static new_in(value: T, alloc: A) -> Rc<T, A>;
static try_new(value: T) -> Result<Rc<T, GlobalAlloc>, AllocError>;
static try_new_in(value: T, alloc: A) -> Result<Rc<T, A>, AllocError>;
clone(&this) -> Rc<T, A>;
downgrade(&this) -> Weak<T, A>;
strong_count(&this) -> u64;
weak_count(&this) -> u64;
as_ptr(&this) -> T*;
get_ref(&this) -> T*;
get_mut(mut &this) -> Option<T*>;
}
Shared ownership within one thread. Rc shares ownership of a heap value among many holders. The value lives until the last strong handle drops, at which point T::drop() runs; the storage comes back once the last weak handle is gone too.
Rcis not thread-safe. The counts are plainu64s with no synchronization. Sending one across threads, or cloning it from two threads at once, is a data race — useArc.
get_mut is the sound way to mutate an Rc-managed value. It hands back a pointer only when there is exactly one strong reference and no outstanding Weak — either could otherwise alias the value, a Weak by upgrading into a second strong handle.
Properties
| Property | Type |
|---|---|
inner | RcInner<T, A>* |
Constructors
static new(value: T) -> Rc<T, GlobalAlloc>;
static new(value: T) -> Rc<T, GlobalAlloc>;Allocate a new Rc backed by GlobalAlloc with an initial count of 1. Panics if the allocator refuses the request; use try_new to handle OOM.
static new_in(value: T, alloc: A) -> Rc<T, A>;
static new_in(value: T, alloc: A) -> Rc<T, A>;Allocate with a caller-supplied allocator. Panics on allocation failure; use try_new_in for fallible construction.
static try_new(value: T) -> Result<Rc<T, GlobalAlloc>, AllocError>;
static try_new(value: T) -> Result<Rc<T, GlobalAlloc>, AllocError>;Fallible constructor backed by GlobalAlloc. Returns Err(AllocError) if the allocator refuses the request.
static try_new_in(value: T, alloc: A) -> Result<Rc<T, A>, AllocError>;
static try_new_in(value: T, alloc: A) -> Result<Rc<T, A>, AllocError>;Fallible constructor with a caller-supplied allocator. The allocator instance is stored in the inner header and is used to free the inner when the last reference drops.
Methods
clone(&this) -> Rc<T, A>;
clone(&this) -> Rc<T, A>;Produce another Rc pointing at the same value. Increments the strong count; the two handles are interchangeable. Allocator is shared through the inner pointer; no copy needed.
downgrade(&this) -> Weak<T, A>;
downgrade(&this) -> Weak<T, A>;A non-owning Weak handle to the same value. Bumps the weak count but not the strong count, so it will not keep the value alive.
strong_count(&this) -> u64;
strong_count(&this) -> u64;Current strong-reference count. Primarily useful for tests and assertions; acting on this value in a running program is rarely the right move.
weak_count(&this) -> u64;
weak_count(&this) -> u64;Number of live Weak handles. The strong group's shared unit is excluded, so this is 0 when no Weak has been created.
as_ptr(&this) -> T*;
as_ptr(&this) -> T*;Raw pointer to the shared value. Valid for as long as any strong clone of this Rc is still alive; dereferencing after the last drop is undefined.
get_ref(&this) -> T*;
get_ref(&this) -> T*;Shared borrow of the value. Sound for reads while any strong clone is alive. Prefer over as_ptr for the read path. Do NOT mutate through this when other clones exist - use get_mut, which is gated on uniqueness.
get_mut(mut &this) -> Option<T*>;
get_mut(mut &this) -> Option<T*>;Mutable borrow of the value, but only when this is the sole owner: exactly one strong reference AND no outstanding Weak (either could otherwise alias the value - a Weak by upgrading to a second strong). Otherwise None. This is the sound way to mutate an Rc-managed value.
Weak<T, A>
type struct Weak<T, A = GlobalAlloc> {
inner: RcInner<T, A>*;
static new() -> Weak<T, GlobalAlloc>;
upgrade(&this) -> Option<Rc<T, A>>;
clone(&this) -> Weak<T, A>;
strong_count(&this) -> u64;
}
A Weak<T, A> does not keep the value alive. Once every strong handle is gone the value is dropped and upgrade returns None from then on. This is the tool for breaking reference cycles: hold the back-edge of a cycle as a Weak and it will not leak.
Weak::new() allocates nothing and never upgrades — useful as a placeholder before a cycle is wired up.
Properties
| Property | Type |
|---|---|
inner | RcInner<T, A>* |
Constructors
static new() -> Weak<T, GlobalAlloc>;
static new() -> Weak<T, GlobalAlloc>;A Weak that never upgrades. Allocates nothing; upgrade always returns None. Useful as a placeholder before a cycle is wired up.
Methods
upgrade(&this) -> Option<Rc<T, A>>;
upgrade(&this) -> Option<Rc<T, A>>;Try to obtain a strong Rc. Returns None once the last strong reference has gone (the value has been dropped), or for a dangling Weak::new(). On success the strong count is bumped, so the returned Rc keeps the value alive.
clone(&this) -> Weak<T, A>;
clone(&this) -> Weak<T, A>;Another Weak to the same value. Bumps the weak count.
strong_count(&this) -> u64;
strong_count(&this) -> u64;Live strong count, or 0 for a dangling Weak. Advisory.
Why teardown has two phases
type struct RcInner<T, A> {
strong: u64;
weak: u64;
value: T;
alloc: A;
}
The header carries two counts. strong tracks live Rc handles. weak tracks live Weak handles plus one shared unit owned by the strong group, so it never drops below 1 while any Rc exists.
When strong hits zero the value is dropped and the strong group releases its shared unit. When weak then hits zero — on that same drop, or later when the last surviving Weak goes away — the header is freed. That split is what lets a Weak safely outlive the value: the header, and the strong flag upgrade reads, stays mapped until no handle of either kind remains.
Properties
| Property | Type |
|---|---|
strong | u64 |
weak | u64 |
value | T |
alloc | A |
Trait implementations
Rc
implement<T, A> trait Drop for struct Rc<T, A> where A: Allocator
Weak
implement<T, A> trait Drop for struct Weak<T, A> where A: Allocator
clone is an inherent method rather than a Clone impl, so generic code that wants T: Clone on the pointee is not confused by a cheap handle copy.
type struct Name { ... }
type enum Name { ... }
type trait Name { ... }
type union Name { ... }Begins a type declaration; the keyword that follows says which kind. On its own, type Name = Existing; declares an alias.
type struct Name {
field: Type;
method(&this) -> Ret { ... }
}A value type with named fields and optional methods. Structs live on the stack and are passed by value. Fields are public by default and may carry = default values; methods take their receiver as &this, mut &this, or this.
type struct Rc<T, A = GlobalAlloc> where A: Allocator {
inner: RcInner<T, A>*;
}Rc<T, A>: single-threaded reference counting, with weak references.
type parameter Ttype parameter Awhere A: Allocator
type struct GlobalAlloc {}Zero-sized handle to the process-wide allocator. Construct with GlobalAlloc::new(); all instances dispatch through the same underlying backend.
where T: Ord + Clone, U: HashConstrains generic parameters to types that implement the listed traits, which is what makes those traits' methods callable on T. Bounds on one parameter join with +; parameters separate with ,. A where on a single method narrows the type's parameter for that method only.
type trait Allocator {
allocate(mut &this, layout: Layout) -> Result<NonNull<u8>, AllocError>;
deallocate(mut &this, ptr: NonNull<u8>, layout: Layout) -> void;
reallocate(mut &this, ptr: NonNull<u8>, old_layout: Layout, new_layout: Layout) -> Result<NonNull<u8>, AllocError>;
}Allocator: the trait every heap strategy implements.
std::alloc::allocatorRc.inner: RcInner<T, A>*type struct RcInner<T, A> {
strong: u64;
weak: u64;
value: T;
alloc: A;
}Heap-resident header shared by every Rc<T, A> and Weak<T, A> for one value. The allocator instance lives here, not in the handles, so all of them agree on who frees the inner when the last reference drops.
type parameter Tstatic name(param: Type) -> Ret { ... }A method that belongs to the type rather than an instance, called as Type::name(..). For structs, static new(..) returning a struct literal is the idiomatic constructor.
static Rc::new(value: T) -> Rc<T, GlobalAlloc>Allocate a new Rc backed by GlobalAlloc with an initial count of 1. Panics if the allocator refuses the request; use try_new to handle OOM.
(parameter) value: Ttype struct Rc<T, A = GlobalAlloc> where A: Allocator {
inner: RcInner<T, A>*;
}Rc<T, A>: single-threaded reference counting, with weak references.
std::alloc::rcstatic Rc::new_in(value: T, alloc: A) -> Rc<T, A>Allocate with a caller-supplied allocator. Panics on allocation failure; use try_new_in for fallible construction.
(parameter) alloc: Astatic Rc::try_new(value: T) -> Result<Rc<T, GlobalAlloc>, AllocError>Fallible constructor backed by GlobalAlloc. Returns Err(AllocError) if the allocator refuses the request.
type struct AllocError {
kind: AllocErrorKind;
layout: Layout;
}static Rc::try_new_in(value: T, alloc: A) -> Result<Rc<T, A>, AllocError>Fallible constructor with a caller-supplied allocator. The allocator instance is stored in the inner header and is used to free the inner when the last reference drops.
Rc::clone(&this) -> Rc<T, A>Produce another Rc pointing at the same value. Increments the strong count; the two handles are interchangeable. Allocator is shared through the inner pointer; no copy needed.
&this
mut &this
thisThe receiver of a method. Its first parameter declares how the method takes it: &this borrows read-only, mut &this borrows exclusively, and this / mut this move the value in and consume it. In the body, this.field reaches the members.
Rc::downgrade(&this) -> Weak<T, A>A non-owning Weak handle to the same value. Bumps the weak count but not the strong count, so it will not keep the value alive.
type struct Weak<T, A = GlobalAlloc> {
inner: RcInner<T, A>*;
}A non-owning reference to an Rc-managed value. Obtain one with Rc::downgrade; recover a strong Rc (if the value still lives) with upgrade. Holding a Weak keeps the header mapped but not the value, which is what makes it safe to store the back-edge of a cycle here.
Rc::strong_count(&this) -> u64Current strong-reference count. Primarily useful for tests and assertions; acting on this value in a running program is rarely the right move.
Rc::weak_count(&this) -> u64Number of live Weak handles. The strong group's shared unit is excluded, so this is 0 when no Weak has been created.
Rc::as_ptr(&this) -> T*Raw pointer to the shared value. Valid for as long as *any* strong clone of this Rc is still alive; dereferencing after the last drop is undefined.
Rc::get_ref(&this) -> T*Shared borrow of the value. Sound for reads while any strong clone is alive. Prefer over as_ptr for the read path. Do NOT mutate through this when other clones exist - use get_mut, which is gated on uniqueness.
Rc::get_mut(mut &this) -> Option<T*>Mutable borrow of the value, but only when this is the sole owner: exactly one strong reference AND no outstanding Weak (either could otherwise alias the value - a Weak by upgrading to a second strong). Otherwise None. This is the sound way to mutate an Rc-managed value.
mut &this
mut &TypeAn exclusive, mutating borrow. As a receiver, mut &this lets the method modify the fields - and callers can see that from the signature alone. As a parameter type, mut &T lets the callee mutate through the reference while the caller keeps ownership.
type struct Weak<T, A = GlobalAlloc> {
inner: RcInner<T, A>*;
}A non-owning reference to an Rc-managed value. Obtain one with Rc::downgrade; recover a strong Rc (if the value still lives) with upgrade. Holding a Weak keeps the header mapped but not the value, which is what makes it safe to store the back-edge of a cycle here.
type parameter AWeak.inner: RcInner<T, A>*type parameter Ttype parameter Astatic Weak::new() -> Weak<T, GlobalAlloc>A Weak that never upgrades. Allocates nothing; upgrade always returns None. Useful as a placeholder before a cycle is wired up.
Weak::upgrade(&this) -> Option<Rc<T, A>>Try to obtain a strong Rc. Returns None once the last strong reference has gone (the value has been dropped), or for a dangling Weak::new(). On success the strong count is bumped, so the returned Rc keeps the value alive.
Weak::clone(&this) -> Weak<T, A>Another Weak to the same value. Bumps the weak count.
Weak::strong_count(&this) -> u64Live strong count, or 0 for a dangling Weak. Advisory.
type struct RcInner<T, A> {
strong: u64;
weak: u64;
value: T;
alloc: A;
}Heap-resident header shared by every Rc<T, A> and Weak<T, A> for one value. The allocator instance lives here, not in the handles, so all of them agree on who frees the inner when the last reference drops.
RcInner.strong: u64RcInner.weak: u64RcInner.value: Ttype parameter TRcInner.alloc: Atype parameter Aimport a::b;
import a::b::{ X, Y };
import a::b as c;
import a::b::*;Brings a module, or selected items from it, into scope. One path per declaration: use the brace form for several items, as to alias, and * for everything public (prefer the brace form; wildcards invite name collisions).
namespace std::alloc::rc;Rc<T, A>: single-threaded reference counting, with weak references.
module pagetype struct Arc<T, A = GlobalAlloc> where A: Allocator {
inner: ArcInner<T, A>*;
}Arc<T, A>: atomic reference counting, with weak references.
std::alloc::arcRc::get_mut(mut &this) -> Option<T*>Mutable borrow of the value, but only when this is the sole owner: exactly one strong reference AND no outstanding Weak (either could otherwise alias the value - a Weak by upgrading to a second strong). Otherwise None. This is the sound way to mutate an Rc-managed value.
Weak.inner: RcInner<T, A>*static Weak::new() -> Weak<T, GlobalAlloc>A Weak that never upgrades. Allocates nothing; upgrade always returns None. Useful as a placeholder before a cycle is wired up.
static Rc::try_new(value: T) -> Result<Rc<T, GlobalAlloc>, AllocError>Fallible constructor backed by GlobalAlloc. Returns Err(AllocError) if the allocator refuses the request.
static Rc::new_in(value: T, alloc: A) -> Rc<T, A>Allocate with a caller-supplied allocator. Panics on allocation failure; use try_new_in for fallible construction.
static Rc::try_new_in(value: T, alloc: A) -> Result<Rc<T, A>, AllocError>Fallible constructor with a caller-supplied allocator. The allocator instance is stored in the inner header and is used to free the inner when the last reference drops.
std::alloc::rcResult::Err(E)Rc::downgrade(&this) -> Weak<T, A>A non-owning Weak handle to the same value. Bumps the weak count but not the strong count, so it will not keep the value alive.
Weak::strong_count(&this) -> u64Live strong count, or 0 for a dangling Weak. Advisory.
Rc::weak_count(&this) -> u64Number of live Weak handles. The strong group's shared unit is excluded, so this is 0 when no Weak has been created.
Rc::as_ptr(&this) -> T*Raw pointer to the shared value. Valid for as long as *any* strong clone of this Rc is still alive; dereferencing after the last drop is undefined.
Rc::get_ref(&this) -> T*Shared borrow of the value. Sound for reads while any strong clone is alive. Prefer over as_ptr for the read path. Do NOT mutate through this when other clones exist - use get_mut, which is gated on uniqueness.
Option::NoneWeak::upgrade(&this) -> Option<Rc<T, A>>Try to obtain a strong Rc. Returns None once the last strong reference has gone (the value has been dropped), or for a dangling Weak::new(). On success the strong count is bumped, so the returned Rc keeps the value alive.
RcInner.strong: u64RcInner.weak: u64RcInner.value: TRcInner.alloc: Aimplement struct Name { ... }
implement trait Trait for Type { ... }
implement u64 { ... }Adds methods to a type outside its declaration. implement struct T (or enum, or a bare primitive) opens an inherent block; implement trait Tr for T supplies a trait's methods for one type. Resolution is at compile time - no dynamic dispatch.
type trait Name : Base {
method(&this, other: &This) -> Ret;
}Names a set of methods a type may implement. Inside the body This is the implementing type; methods may carry default bodies, and a trait may require a base trait (type trait Ord : Eq). Generic code asks for a trait with where T: Name.
implement trait Trait for Type { ... }Names the type a trait implementation is for. The block that follows supplies the bodies the trait requires.
language reference