3

Is there a way to move an object from an Rc<T> when the count is 1? I am thinking about how one would implement:

fn take_ownership<T>(shared: Rc<T>) -> Result<T, Rc<T>> { ... }

The semantics would be that you get T if the count is 1 and you get back shared otherwise so you can try again later.

Victor Savu
  • 936
  • 14
  • 19
  • 5
    https://doc.rust-lang.org/std/rc/struct.Rc.html#method.try_unwrap – red75prime Aug 06 '17 at 09:35
  • Thanks! Ok, this is embarrassing. When I initially search the documentation I looked for an Optional return and that is why I missed this function. Then I realized Result would be more useful, but I was already convinced the answer was not in the docs due to the previous search. Logical fail :( – Victor Savu Aug 06 '17 at 09:38
  • 1
    @red75prime: Might as well post this as an answer so it can be accepted and we can all move on :) – Matthieu M. Aug 06 '17 at 11:13
  • See also [How to take ownership of T from Arc>?](https://stackoverflow.com/q/29177449/155423). – Shepmaster Aug 06 '17 at 13:13

1 Answers1

3

The standard library provides the Rc::try_unwrap function:

fn try_unwrap(this: Rc<T>) -> Result<T, Rc<T>>

Returns the contained value, if the Rc has exactly one strong reference.

Otherwise, an Err is returned with the same Rc that was passed in.

This will succeed even if there are outstanding weak references.

Examples

use std::rc::Rc;

let x = Rc::new(3);
assert_eq!(Rc::try_unwrap(x), Ok(3));

let x = Rc::new(4);
let _y = Rc::clone(&x);
assert_eq!(*Rc::try_unwrap(x).unwrap_err(), 4);
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
red75prime
  • 3,733
  • 1
  • 16
  • 22