Я пытаюсь написать структуру контейнера в Rust, где его элементы также хранят ссылку на содержащий контейнер, чтобы они могли вызывать на нем методы. Насколько я мог понять, мне нужно сделать это через Rc<RefCell<T>>
. Это верно?Ссылка на содержащую структуру в Rust (и методы вызова на нем)
До сих пор, у меня есть что-то вроде следующего:
struct Container {
elems: ~[~Element]
}
impl Container {
pub fn poke(&mut self) {
println!("Got poked.");
}
}
struct Element {
datum: int,
container: Weak<RefCell<Container>>
}
impl Element {
pub fn poke_container(&mut self) {
let c1 = self.container.upgrade().unwrap(); // Option<Rc>
let mut c2 = c1.borrow().borrow_mut(); // &RefCell
c2.get().poke();
// self.container.upgrade().unwrap().borrow().borrow_mut().get().poke();
// -> Error: Borrowed value does not live long enough * 2
}
}
fn main() {
let container = Rc::new(RefCell::new(Container{ elems: ~[] }));
let mut elem1 = Element{ datum: 1, container: container.downgrade() };
let mut elem2 = Element{ datum: 2, container: container.downgrade() };
elem1.poke_container();
}
Я чувствую, что я пропускаю что-то здесь. Является ли доступ к содержимому Rc<RefCell<T>>
действительно сложным (в poke_container
)? Или я подхожу к проблеме не так?
И наконец, если предположить, что подход является правильным, как бы я написать add
метод Container
так, чтобы он мог заполнить container
поле в Element
(предполагая, что я изменил поле, чтобы иметь тип Option<Rc<RefCell<T>>>
? Я не могу создать другой Rc
от &mut self
0 насколько я знаю.
BTW, нет необходимости использовать '~ [~ Element]' вместо '~ [Element]'. –
@ Vladimir Правда, спасибо, но в моем фактическом коде «Элемент» - это черта, поэтому я думаю, что я не могу оставить «~» в этом случае. – Kolja
Да, вы правы, в этом случае вам понадобится '~'. Что касается вопроса, я не вижу, как вы могли бы упростить доступ к содержимому окна «Rc». Вот как это работает сейчас. Хотелось бы надеяться, что было бы проще, когда реальный «Gc» приземлится (так что не понадобится обертка «Weak»), и когда будет доступно избыточное разыменование (никаких дополнительных вызовов «заимствования» и «заимствования»)(). –