Короткий ответ
Нет, невозможно создать Rc<T>
из Rc<Option<T>>
, который оставляет последнее все еще существующим. Однако можно создать Rc<&T>
из Rc<Option<T>>
, оставив при этом последнюю переменную существующей.
Длинный ответ
Если вы пытаетесь создать новый Rc<T>
, которому принадлежит T
внутри Rc<Option<T>>
, вам придется использовать исходный Rc<Option<T>>
. Вы также не можете иметь несколько экземпляров Rc<Option<T>>
, потому что тогда вы перемещаете общее значение, пока еще существуют указатели, что очень небезопасно.
Но есть способ сделать это безопасно! Используя Rc::try_unwrap
, вы можете попытаться переместить значение наружу, но это вернет ошибку, если существует несколько экземпляров исходного Rc
.
Имейте в виду, что вам также придется справиться со сценарием, в котором Option<T>
в конечном итоге становится None
.
Вот пример этого:
let rc_option: Rc<Option<T>> = Rc::new(Some(value));
match Rc::try_unwrap(rc_option) {
Ok(option) => {
match option {
Some(t) => {
let ok_value: Rc<T> = Rc::new(t);
// Do something with ok_value
}
None => {
// Do something else here
}
}
}
Err(rc_option) => {
// There are multiple owners, do something else here
}
}
Если вы хотите сохранить оригинал, вы можете сделать это:
match &*rc_option {
Some(ref t) => {
let ok_ref: Rc<&T> = Rc::new(t);
}
None => { /* Do something else, there's no internal value */ }
}
РЕДАКТИРОВАТЬ: Как упоминалось в Chronial, обратите внимание, что ok_ref
не может пережить rc_option
(потому что это ссылка на rc_option
), что, возможно, не то, что вы хотите, чтобы.