Условно переместите T из Rc‹T›, когда счет равен 1

Есть ли способ переместить объект из Rc<T>, когда счет равен 1? Я думаю о том, как можно было бы реализовать:

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

Семантика будет заключаться в том, что вы получите T, если счет равен 1, и вы получите обратно shared в противном случае, чтобы вы могли повторить попытку позже.


person Victor Savu    schedule 06.08.2017    source источник
comment
doc.rust-lang.org/std/rc/ struct.Rc.html#method.try_unwrap   -  person red75prime    schedule 06.08.2017
comment
Спасибо! Хорошо, это неловко. Когда я впервые искал документацию, я искал возврат Optional‹T›, и поэтому я пропустил эту функцию. Потом я понял, что Result будет полезнее, но я уже был уверен, что ответа нет в документах из-за предыдущего поиска. Логический сбой :(   -  person Victor Savu    schedule 06.08.2017
comment
@red75prime: Можно также опубликовать это как ответ, чтобы его можно было принять, и мы все могли двигаться дальше :)   -  person Matthieu M.    schedule 06.08.2017
comment
См. также Как стать владельцем T у Arc‹Mutex‹T››?.   -  person Shepmaster    schedule 06.08.2017


Ответы (1)


Стандартная библиотека предоставляет функцию Rc::try_unwrap:

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

Возвращает содержащееся значение, если Rc имеет ровно одну сильную ссылку.

В противном случае возвращается Err с тем же Rc, которое было передано.

Это удастся, даже если есть незавершенные слабые ссылки.

Примеры

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);
person red75prime    schedule 07.08.2017