Имея R c<T> с в одном модуле и R c в другой ссылаются на те же данные - PullRequest
0 голосов
/ 02 марта 2020

У меня есть такая структура данных:

mod nodes {
    struct Node {
        predecessors: Vec<Rc<Node>>
    }
}

Мне явно не нужна изменчивость узлов в этом модуле. У меня также нет циклических c ссылок здесь.

Но у меня есть другой модуль, который содержит узлы, где мне нужна изменчивость:

pub mod network {
    mod nodes {...}

    struct Network {
        nodes: Vec<Vec<Rc<RefCell<Node>>>>
    }
}

Я просто не могу понять способ создания Rc<Node> s для самих узлов вместе с Rc<RefCell<Node>> s для Network.

Есть ли у вас какие-либо идеи о том, как реализовать неизменяемость в модуле nodes далее? к изменяемым узлам в модуле network?

Или нет другого способа, кроме как объявить ссылки на узлы-предшественники в структуре Node как Rc<RefCell<Node>>, хотя мне и не нужно изменчивость здесь (я бы хотел этого избежать)?

1 Ответ

1 голос
/ 02 марта 2020

Rust имеет единоличное владение . Если Node принадлежит RefCell, он также не может принадлежать другому Rc в то же время.

Когда Node можно изменить в одном месте с помощью RefCell эти изменения не могут быть обнаружены в другом месте в Rc<Node>. Это нарушило бы неизменность Rc<Node>.

Также обратите внимание, что Node является структурным значением, а не указателем на объект. Нет никакого дополнительного уровня косвенности, который мог бы даже разделить его между RefCell и другими Rc. Его данные копируются и помещаются в контейнер.

  • Попробуйте использовать Rc<RefCell<Node>> в обоих местах. Если одни и те же данные используются в обоих местах, они должны поддерживать все гарантии в обоих местах, даже если вы этим не пользуетесь.

  • Если вы не используете оба В то же время вы можете преобразовывать один тип в другой, деконструируя его (into_inner, try_unwrap) и снова создавая другой тип. Это преобразование не является бесплатным, поскольку разметка физической памяти этих типов отличается.

  • Если вам требуется только изменчивость, Rc имеет make_mut, который работает без RefCell. И RefCell имеет нулевую стоимость get_mut, если у вас уже есть изменяемый доступ к нему, так что вы можете уменьшить их накладные расходы в определенных c случаях.

...