"ожидаемая структура` std :: rc :: Rc`, найденная ссылка "- как конвертировать? - PullRequest
2 голосов
/ 10 марта 2019

Я пытался получить счетчик ссылок Rc<Foo> из хеш-карты и поместить его в другой контейнер (Vec<Foo>).

Подумал, что это сработает (путем увеличения счетчика ссылок), новместо этого я получил "ожидаемую структуру std::rc::Rc, найденную ссылку" error.

Как мне преобразовать &Rc<Foo> в Rc<Foo>?


Дополнительная информация:

struct Foo();
let mut foo : HashMap<usize, Rc<Foo>> = HashMap::new();
let mut bar : Vec<Rc<Foo>> = Vec::new();
foo.insert(0, Rc::new(Foo()));
if let Some(x) = foo.get(&0) {
    bar.push(x); // expected struct `std::rc::Rc`, found reference
                 // note: expected type `std::rc::Rc<Foo>`
                 //          found type `&std::rc::Rc<Foo>`  rustc(E0308)
}

Я получаю, что хэш-карта возвращает ссылку на принадлежащее ей значение.Но разыменование не работает: и if let Some(&x), и bar.push(*x); приводят к "не может быть перемещен из заимствованного содержимого" .

Любопытно, что добавление аннотации типа изменяет ошибку на "не может выйти из Rc" :

    let x : &Rc<Foo> = x;
    bar.push(*x); // cannot move out of an `Rc`  rustc(E0507)

Мне нужно хранить ссылку на тот же объект, а не на копию, поэтому я избегал .clone()"аварийный люк".

1 Ответ

2 голосов
/ 10 марта 2019

Чтобы преобразовать &Rc<Foo> -> Rc<Foo>, используйте Rc::clone(), который дает вам собственный объект Rc, увеличивая количество ссылок под капотом:

let ref_to_rc: &Rc<Foo> = &Rc::new(Foo());
let new_rc: Rc<Foo> = Rc::clone(ref_to_rc);

rc.clone() эквивалентно Rc::clone(&rc), но идиоматический Rust использует последнее, чтобы прояснить, что код увеличивает только пересчет, не выполняя глубокое копирование данных, как некоторые другие реализации .clone() делать. ( Хотя в некоторых сценариях с чертами вам может потребоваться вернуться к ref_to_rc.clone().)

Приведенные выше ошибки были связаны с тем, что Rust отказался делать копию неявно. Почему std :: rc :: Rc <> не Copy? содержит объяснение, почему он так себя ведет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...