pub struct Rc<T> { /* private fields */ }
Expand description
Rc<T>
is a reference-counting pointer for single-threaded use, for
multi-threaded use cases you should use Arc<T>
.
Rc<T>
provides shared ownership of a value of type T that is stored in
the heap. When you clone an Rc, it creates a new pointer to the same heap
allocation. When the last Rc pointer to the allocation is destroyed, the
stored value is also dropped.
Implementations§
Source§impl<T> Rc<T>
impl<T> Rc<T>
Sourcepub fn pin(value: T) -> Pin<Rc<T>>
pub fn pin(value: T) -> Pin<Rc<T>>
Constructs a new Pin<Rc<T>>
. If T
does not implement Unpin
, then
value
will be pinned in memory and unable to be moved.
Sourcepub fn as_ptr(&self) -> *const T
pub fn as_ptr(&self) -> *const T
Gives you a pointer to the data. The reference count stays the same and
the Rc<T>
isn’t used up. The pointer stays valid as long as there
are strong references to the Rc<T>
.
§Examples
use rclite::Rc;
let x = Rc::new("hello".to_owned());
let y = Rc::clone(&x);
let x_ptr = Rc::as_ptr(&x);
assert_eq!(x_ptr, Rc::as_ptr(&y));
assert_eq!(unsafe { &*x_ptr }, "hello");
Sourcepub fn into_raw(this: Self) -> *const T
pub fn into_raw(this: Self) -> *const T
Turns Rc<T>
into a raw pointer, must be converted back to Rc<T>
with Rc::from_raw
to avoid memory leak.
§Examples
use rclite::Rc;
let x = Rc::new("hello".to_owned());
let x_ptr = Rc::into_raw(x);
assert_eq!(unsafe { &*x_ptr }, "hello");
// reconstruct Rc to drop the reference and avoid memory leaks
unsafe { Rc::from_raw(x_ptr) };
Sourcepub unsafe fn from_raw(ptr: *const T) -> Self
pub unsafe fn from_raw(ptr: *const T) -> Self
Constructs an Rc<T>
from a raw pointer. The raw pointer must have
been from Rc<U>::into_raw
where U and T must have the same size
and alignment. Improper use may lead to memory unsafe operations.
§Safety
It’s only safe to construct back references that are generated with
Rc::into_raw
, converting any other references may lead to undefined
behaivior.
§Examples
use rclite::Rc;
let x = Rc::new("hello".to_owned());
let x_ptr = Rc::into_raw(x);
unsafe {
// Convert back to an [`Rc<T>`] to prevent leak.
let x = Rc::from_raw(x_ptr);
assert_eq!(&*x, "hello");
// Further calls to [`Rc::from_raw(x_ptr)`] would be memory-unsafe.
}
// The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling!
Sourcepub fn strong_count(&self) -> usize
pub fn strong_count(&self) -> usize
Gets the number of strong pointers to an allocation.
§Examples
use rclite::Rc;
let five = Rc::new(5);
let _also_five = Rc::clone(&five);
// This assertion is deterministic because we haven't shared
// the [`Rc<T>`] between threads.
assert_eq!(2, Rc::strong_count(&five));
Sourcepub fn ptr_eq(this: &Self, other: &Self) -> bool
pub fn ptr_eq(this: &Self, other: &Self) -> bool
Compares if two Rc<T>
s reference the same allocation, similar to
ptr::eq. Note: The same caveats apply when comparing dyn Trait
pointers.
§Examples
use rclite::Rc;
let five = Rc::new(5);
let same_five = Rc::clone(&five);
let other_five = Rc::new(5);
assert!(Rc::ptr_eq(&five, &same_five));
assert!(!Rc::ptr_eq(&five, &other_five));
Sourcepub fn get_mut(this: &mut Self) -> Option<&mut T>
pub fn get_mut(this: &mut Self) -> Option<&mut T>
Returns a mutable reference to the inner value of an Rc, but only if there are no other references to it. Returns None otherwise.
§Examples
use rclite::Rc;
let mut x = Rc::new(3);
*Rc::get_mut(&mut x).unwrap() = 4;
assert_eq!(*x, 4);
let _y = Rc::clone(&x);
assert!(Rc::get_mut(&mut x).is_none());
Sourcepub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T
pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T
Returns a mutable reference into the given Rc
without checking if it
is safe to do so.
This method is faster than get_mut
since it avoids any runtime
checks. However, it is unsafe to use unless you can guarantee that
no other Rc
pointers to the same allocation exist and that they are
not dereferenced or have active borrows for the duration
of the returned borrow.
§Safety
You can use get_mut_unchecked
if all of the following conditions are
met:
- No other
Rc
pointers to the same allocation exist. - The inner type of all
Rc
pointers is exactly the same (including lifetimes). - No other
Rc
pointers are dereferenced or have active borrows for the duration of the returned mutable borrow.
These conditions are trivially satisfied immediately after creating a
new Rc
with Rc::new
.
§Examples
use rclite::Rc;
let mut x = Rc::new(String::new());
unsafe {
Rc::get_mut_unchecked(&mut x).push_str("foo")
}
assert_eq!(*x, "foo");
Sourcepub fn try_unwrap(this: Self) -> Result<T, Self>
pub fn try_unwrap(this: Self) -> Result<T, Self>
If there’s only one strong reference, returns the inner value. If not, returns an error with the Rc passed in.
§Examples
use rclite::Rc;
let x = Rc::new(3);
assert_eq!(Rc::try_unwrap(x).unwrap(), 3);
let x = Rc::new(4);
let _y = Rc::clone(&x);
assert_eq!(*Rc::try_unwrap(x).unwrap_err(), 4);
Sourcepub fn into_inner(this: Self) -> Option<T>
pub fn into_inner(this: Self) -> Option<T>
Extracts and returns the inner value from an Rc
if it has exactly one
strong reference.
If the Rc
has more than one strong reference or outstanding weak
references, it returns None
and drops the Rc
.
By calling Rc::into_inner
on every clone of this Rc
, it is
guaranteed that exactly one of the calls will return the inner
value. This ensures that the inner value is not dropped.
Example:
use rclite::Rc;
let value = Rc::new(42);
let cloned1 = Rc::clone(&value);
let cloned2 = Rc::clone(&value);
// it's not sole owner so it will be dropped and will return none
assert!(Rc::into_inner(cloned1).is_none());
// it's not sole owner so it will be dropped and will return none
assert!(Rc::into_inner(value).is_none());
// it is sole reference to the data so it will return the data inside
assert_eq!(Rc::into_inner(cloned2).unwrap(), 42);
This function is equivalent to Rc::try_unwrap(this).ok()
. (Note that
these are not equivalent for Arc
, due to race
conditions that do not apply to Rc
.
Source§impl<T: Clone> Rc<T>
impl<T: Clone> Rc<T>
Sourcepub fn unwrap_or_clone(this: Self) -> T
pub fn unwrap_or_clone(this: Self) -> T
If there’s only one reference to T, remove it. Otherwise, make a copy of
T. If rc_t is of type Rc<T>
, this function works like
(*rc_t).clone(), but will avoid copying the value if possible.
§Examples
use rclite::Rc;
let inner = String::from("test");
let ptr = inner.as_ptr();
let rc = Rc::new(inner);
let inner = Rc::unwrap_or_clone(rc);
// The inner value was not cloned
assert_eq!(ptr, inner.as_ptr());
let rc = Rc::new(inner);
let rc2 = rc.clone();
let inner = Rc::unwrap_or_clone(rc);
// Because there were 2 references, we had to clone the inner value.
assert_ne!(ptr, inner.as_ptr());
// `rc2` is the last reference, so when we unwrap it we get back
// the original `String`.
let inner = Rc::unwrap_or_clone(rc2);
assert_eq!(ptr, inner.as_ptr());
Sourcepub fn make_mut(this: &mut Rc<T>) -> &mut T
pub fn make_mut(this: &mut Rc<T>) -> &mut T
Returns a mutable reference to the inner value of the given Rc
,
ensuring that it has unique ownership.
If there are other Rc
pointers to the same allocation, then
make_mut
will clone the inner value to a new allocation to ensure
unique ownership. This is also referred to as “clone-on-write”.
Unlike get_mut
, which only returns a mutable reference if there are no
other pointers to the same allocation, make_mut
always returns a
mutable reference to the unique allocation.
§Examples
use rclite::Rc;
let mut data = Rc::new(5);
*Rc::make_mut(&mut data) += 1; // Won't clone anything
let mut other_data = Rc::clone(&data); // Won't clone inner data
*Rc::make_mut(&mut data) += 1; // Clones inner data
*Rc::make_mut(&mut data) += 1; // Won't clone anything
*Rc::make_mut(&mut other_data) *= 2; // Won't clone anything
// Now `data` and `other_data` point to different allocations.
assert_eq!(*data, 8);
assert_eq!(*other_data, 12);
§See also
Trait Implementations§
Source§impl<T> AsRef<T> for Rc<T>
An implementation of the AsRef
trait for Rc<T>
.
impl<T> AsRef<T> for Rc<T>
An implementation of the AsRef
trait for Rc<T>
.
This allows an Rc<T>
to be treated as a reference to T
.
§Examples
use rclite::Rc;
let data = Rc::new(42);
let reference: &i32 = data.as_ref();
assert_eq!(*reference, 42);
Source§impl<T> Borrow<T> for Rc<T>
This trait allows for a value to be borrowed as a reference to a given type.
It is typically used for generic code that can work with borrowed values of
different types.
impl<T> Borrow<T> for Rc<T>
This trait allows for a value to be borrowed as a reference to a given type. It is typically used for generic code that can work with borrowed values of different types.
This implementation for Rc<T>
allows for an Rc<T>
to be borrowed as a
shared reference to T
.