Struct Weak

Source
pub struct Weak<T>
where T: ?Sized,
{ /* private fields */ }
Expand description

Weak is a version of Drc that holds a non-owning reference to the managed value. The value is accessed by calling upgrade on the Weak pointer, which returns an Option < Drc<T> >.

Since a Weak reference does not count towards ownership, it will not prevent the inner value from being dropped, and the Weak itself makes no guarantees about the value still being present and may return None when upgraded.

A Weak pointer is useful for keeping a temporary reference to the value within Drc without extending its lifetime. It is also used to prevent circular references between Drc pointers, since mutual owning references would never allow either Drc to be dropped. However, this use is generally not recommended for Drcs because “interior” Drcs would be inaccessible and remove Send and Sync from the type, meaning an Rc would be just as good for the task.

Something that might work better is using Arcs and weak Arcs within the structure, with the outermost reference obviously having the potential to be converted into a Drc or Weak Drc (i.e. this Weak).

The typical way to obtain a Weak pointer is to call Drc::downgrade. Using Weak::with_weak_arc is not recommended for most cases, as this performs unnecessary allocation without even knowing if the pointed-to value is still there!

Implementations§

Source§

impl<T> Weak<T>

Source

pub fn new() -> Weak<T>

Constructs a new Weak<T>, allocating memory for not only T and its atomic reference counts but also the local reference counts. Calling upgrade on the return value always gives None.

Exercise restrain when using this method; if possible it is recommended to simply use the weak Arc’s new method for whatever purpose this new method would fulfill.

§Examples
use drc::Weak;

let empty: Weak<i64> = Weak::new();
assert!(empty.upgrade().is_none());
Source§

impl<T> Weak<T>
where T: ?Sized,

Source

pub fn with_weak_arc(weak_arc: WeakArc<T>) -> Weak<T>

Constructs a new Weak pointer, allocating memory for local reference counts, but using a pre-constructed weak Arc. Calling upgrade on the return value may or may not return a Drc. If the Drc can be created, it will make use of this allocated memory.

Exercise restrain when using this method; if possible it is recommended to simply use the weak Arc for whatever purpose this Weak would fulfill.

This method was chosen over an implementation of the from method for a reverse detachment to make it clear that care should be taken when using this operation instead of alternatives.

§Examples
use std::sync::Arc;

use drc::{Drc, Weak};

let five = Arc::new(5);

let weak_five = Weak::with_weak_arc(Arc::downgrade(&five));

let strong_five: Option<Drc<_>> = weak_five.upgrade();
assert!(strong_five.is_some());

// This is not a recommended use of `with_weak_arc`, as the same could be
// done with `Arc`'s `Weak` type.
Source

pub fn upgrade(&self) -> Option<Drc<T>>

Attempts to upgrade the Weak pointer to a Drc, extending the lifetime of the value if successful.

Returns None if the value has since been dropped.

Note that even if there are no Drc strong pointers associated with the same Arc, the value may still persist. Since this Weak associates with a weak Arc, meaning that a Drc may still be returned even if the local strong pointer count is 0 (because a new Arc can be generated by upgrading the internal weak Arc).

§Examples
use drc::Drc;

let five = Drc::new(5);

// This is an Arc associated to the same value.
let detached_five = Drc::detach(&five);

let weak_five = Drc::downgrade(&five);

let strong_five: Option<Drc<_>> = weak_five.upgrade();
assert!(strong_five.is_some());

drop(strong_five);
drop(five);

let strong_five: Option<Drc<_>> = weak_five.upgrade();
assert!(strong_five.is_some());

drop(strong_five);
drop(detached_five);

assert!(weak_five.upgrade().is_none());
Source

pub fn detach(&self) -> WeakArc<T>

Clone the internal weak Arc (incrementing the atomic weak reference count) so that the shared state can be weakly referenced on another thread. Then, return this newly cloned weak Arc. To convert the weak Arc back into this type of Weak (usually not recommended), use Weak::with_weak_arc.

§Examples
use std::sync::Weak as WeakArc;

use drc::Drc;

let five = Drc::new(5);

let weak_five = Drc::downgrade(&five);
let detached_weak_five: WeakArc<_> = weak_five.detach();

assert!(Drc::arc_ptr_eq(
    &weak_five.upgrade().unwrap(),
    &detached_weak_five.upgrade().unwrap()
));

Trait Implementations§

Source§

impl<T> Clone for Weak<T>
where T: ?Sized,

Source§

fn clone(&self) -> Weak<T>

Makes a clone of the Weak pointer that points to the same value.

§Examples
use drc::{Drc, Weak};

let weak_five = Drc::downgrade(&Drc::new(5));

Weak::clone(&weak_five);
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T> Debug for Weak<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult

Formats the value using the given formatter. Read more
Source§

impl<T> Default for Weak<T>

Source§

fn default() -> Weak<T>

Constructs a new Weak<T>, allocating memory for not only T and its atomic reference counts but also the local reference counts. Calling upgrade on the return value always gives None.

Exercise restrain when using this method; if possible it is recommended to simply use the weak Arc’s Default implementation for whatever purpose this new method would fulfill.

§Examples
use drc::Weak;

let empty: Weak<i64> = Default::default();
assert!(empty.upgrade().is_none());
Source§

impl<T> Drop for Weak<T>
where T: ?Sized,

Source§

fn drop(&mut self)

Drops the Weak pointer.

§Examples
use drc::{Drc, Weak};

struct Foo;

impl Drop for Foo {
    fn drop(&mut self) {
        println!("dropped!");
    }
}

let foo = Drc::new(Foo);
let weak_foo = Drc::downgrade(&foo);
let other_weak_foo = Weak::clone(&weak_foo);

drop(weak_foo); // Doesn't print anything
drop(foo); // Prints "dropped!"

assert!(other_weak_foo.upgrade().is_none());

Auto Trait Implementations§

§

impl<T> Freeze for Weak<T>
where T: ?Sized,

§

impl<T> !RefUnwindSafe for Weak<T>

§

impl<T> !Send for Weak<T>

§

impl<T> !Sync for Weak<T>

§

impl<T> Unpin for Weak<T>
where T: ?Sized,

§

impl<T> !UnwindSafe for Weak<T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.