@Eugene523

Как изменить данные завернутые в Box, который завернут в Option?

Как изменить данные завернутые в Box, который завернут в Option?

Дано дерево узлов (Nodes), каждый из которых содержит (точнее может содержать) два потомка. Каждый узел содержит ссылку на родительский узел. В методе set_leftя хочу установить ссылку на родительский объект. Как мне это сделать? Желательно не просто код, а детальное пояснение (вам пишет начинающий).
pub struct Node<'a> {
    parent: Option<&'a Node<'a>>,
    data: u32,
    pub left: Option<Box<Node<'a>>>,
    pub right: Option<Box<Node<'a>>>
}

impl<'a> Node<'a> {
    pub fn new(data: u32) -> Node<'a> {
        Node { 
            parent: None, 
            data,
            left: None,
            right: None,
        }
    }

    pub fn set_left(&mut self, child: Option<Box<Node<'a>>>) {
        self.left = child;
        if self.left.is_some() {
            self.left.parent = ???
        }
    }
}
  • Вопрос задан
  • 112 просмотров
Решения вопроса 1
bingo347
@bingo347
Crazy on performance...
Во-первых стоит познакомится с такой конструкцией, как if let.
Но здесь, с Box, у Вас не получится обойти borrow checker.
Нормальным решением будет использовать счетчики ссылок (Rc или Arc) и избавиться с их помощи от зависимости на лайфтаймы. А для ссылки на parent нужно использовать Weak ссылку, чтоб она не влияла на подсчет ссылок.

https://doc.rust-lang.org/std/rc/struct.Rc.html
https://doc.rust-lang.org/std/rc/struct.Weak.html

https://doc.rust-lang.org/std/sync/struct.Arc.html
https://doc.rust-lang.org/std/sync/struct.Weak.html

use std::rc::{Rc, Weak};

pub struct Node {
    parent: Weak<Node>,
    data: u32,
    pub left: Option<Rc<Node>>,
    pub right: Option<Rc<Node>>,
}

#[derive(Debug)]
pub struct SetChildError;

impl Node {
    pub fn new(data: u32) -> Self {
        Self {
            parent: Weak::new(),
            data,
            left: None,
            right: None,
        }
    }

    pub fn set_left(self: &mut Rc<Self>, mut child: Rc<Self>) -> Result<(), SetChildError> {
        let child_mut = Rc::get_mut(&mut child).ok_or(SetChildError)?;
        child_mut.parent = Rc::downgrade(self);

        let self_mut = Rc::get_mut(self).ok_or(SetChildError)?;
        self_mut.left = Some(child);

        Ok(())
    }
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы