英文:
Extracting an attribute from a Box inside an enum
问题
#[derive(Clone, Debug)]
pub struct Node<T> {
    value: T,
    left: Addr<T>,
    right: Addr<T>,
}
#[derive(Clone, Debug)]
pub enum Addr<T> {
    Addr(Box<Node<T>>),
    None,
}
impl<T> Addr<T> {
    pub fn is_none(&self) -> bool {
        matches!(&*self, Addr::None)
    }
}
impl<T> Node<T> {
    fn node_insert(mut n: Addr<T>, val: T) {
        let nd = Box::new(Node {
            value: val,
            left: Addr::None,
            right: Addr::None,
        });
        if n.is_none() {
            n = Addr::Addr(nd);
        } else {
            // You should access the left attribute like this:
            if let Addr::Addr(node) = n {
                // Access the left attribute of the Node struct
                node.left = node_insert(node.left, val);
            }
        }
    }
}
在 node_insert 函数中,要访问 Node 结构的 left 属性,您应该像上面的示例代码中那样进行访问,使用 if let 来将 n 解构为 Addr::Addr(node),然后您可以访问 node 的 left 属性并调用 node_insert 递归。
英文:
#[derive(Clone, Debug)]
pub struct Node<T> {
    value: T,
    left: Addr<T>,
    right: Addr<T>,
}
#[derive(Clone, Debug)]
pub enum Addr<T> {
    Addr(Box<Node<T>>),
    None,
}
impl<T> Addr<T> {
    pub fn is_none(&self) -> bool {
        matches!(&*self, Addr::None)
    }
}
impl<T> Node<T> {
    fn node_insert(mut n: Addr<T>, val: T) {
        let nd = Box::new(Node {
            value: val,
            left: Addr::None,
            right: Addr::None,
        });
        if n.is_none() {
            n = Addr::Addr(nd);
        } else {
            node_insert(n.left, val);
        }
    }
}
I'm trying to implement a simple binary tree, and in the node_insert function I can't figure out how to access the left attribute of the Node struct when calling node_insert recursively.
Nothing I've done worked and I couldn't find any answer to help with it, probably because its somehow specific.
答案1
得分: 0
使用模式匹配:
fn node_insert(mut n: Addr<T>, val: T) {
    match n {
        Addr::None => {
            n = Addr::Addr(Box::new(Node {
                value: val,
                left: Addr::None,
                right: Addr::None,
            }))
        }
        Addr::Addr(n) => Self::node_insert(n.left, val),
    }
}
然而,编译器正确地发出警告:
warning: value assigned to `n` is never read
  --> src/lib.rs:23:13
   |
23 |             n = Addr::Addr(Box::new(Node {
   |             ^
   |
   = help: maybe it is overwritten before being read?
   = note: `#[warn(unused_assignments)]` on by default
由于您拥有 n,您正在写入一个局部变量而不是树。相反,您应该获取 &mut Addr:
fn node_insert(n: &mut Addr<T>, val: T) {
    match n {
        Addr::None => {
            *n = Addr::Addr(Box::new(Node {
                value: val,
                left: Addr::None,
                right: Addr::None,
            }))
        }
        Addr::Addr(n) => Self::node_insert(&mut n.left, val),
    }
}
英文:
Use pattern matching:
fn node_insert(mut n: Addr<T>, val: T) {
    match n {
        Addr::None => {
            n = Addr::Addr(Box::new(Node {
                value: val,
                left: Addr::None,
                right: Addr::None,
            }))
        }
        Addr::Addr(n) => Self::node_insert(n.left, val),
    }
}
However, the compiler rightfully warns:
warning: value assigned to `n` is never read
  --> src/lib.rs:23:13
   |
23 |             n = Addr::Addr(Box::new(Node {
   |             ^
   |
   = help: maybe it is overwritten before being read?
   = note: `#[warn(unused_assignments)]` on by default
Since you took ownership of n, you're writing to a local variable and not to the tree. Instead, you should take &mut Addr:
fn node_insert(n: &mut Addr<T>, val: T) {
    match n {
        Addr::None => {
            *n = Addr::Addr(Box::new(Node {
                value: val,
                left: Addr::None,
                right: Addr::None,
            }))
        }
        Addr::Addr(n) => Self::node_insert(&mut n.left, val),
    }
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论