从枚举内的一个框中提取属性

huangapple go评论95阅读模式
英文:

Extracting an attribute from a Box inside an enum

问题

  1. #[derive(Clone, Debug)]
  2. pub struct Node<T> {
  3. value: T,
  4. left: Addr<T>,
  5. right: Addr<T>,
  6. }
  7. #[derive(Clone, Debug)]
  8. pub enum Addr<T> {
  9. Addr(Box<Node<T>>),
  10. None,
  11. }
  12. impl<T> Addr<T> {
  13. pub fn is_none(&self) -> bool {
  14. matches!(&*self, Addr::None)
  15. }
  16. }
  17. impl<T> Node<T> {
  18. fn node_insert(mut n: Addr<T>, val: T) {
  19. let nd = Box::new(Node {
  20. value: val,
  21. left: Addr::None,
  22. right: Addr::None,
  23. });
  24. if n.is_none() {
  25. n = Addr::Addr(nd);
  26. } else {
  27. // You should access the left attribute like this:
  28. if let Addr::Addr(node) = n {
  29. // Access the left attribute of the Node struct
  30. node.left = node_insert(node.left, val);
  31. }
  32. }
  33. }
  34. }

node_insert 函数中,要访问 Node 结构的 left 属性,您应该像上面的示例代码中那样进行访问,使用 if let 来将 n 解构为 Addr::Addr(node),然后您可以访问 nodeleft 属性并调用 node_insert 递归。

英文:
  1. #[derive(Clone, Debug)]
  2. pub struct Node&lt;T&gt; {
  3. value: T,
  4. left: Addr&lt;T&gt;,
  5. right: Addr&lt;T&gt;,
  6. }
  7. #[derive(Clone, Debug)]
  8. pub enum Addr&lt;T&gt; {
  9. Addr(Box&lt;Node&lt;T&gt;&gt;),
  10. None,
  11. }
  12. impl&lt;T&gt; Addr&lt;T&gt; {
  13. pub fn is_none(&amp;self) -&gt; bool {
  14. matches!(&amp;*self, Addr::None)
  15. }
  16. }
  17. impl&lt;T&gt; Node&lt;T&gt; {
  18. fn node_insert(mut n: Addr&lt;T&gt;, val: T) {
  19. let nd = Box::new(Node {
  20. value: val,
  21. left: Addr::None,
  22. right: Addr::None,
  23. });
  24. if n.is_none() {
  25. n = Addr::Addr(nd);
  26. } else {
  27. node_insert(n.left, val);
  28. }
  29. }
  30. }

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

使用模式匹配

  1. fn node_insert(mut n: Addr<T>, val: T) {
  2. match n {
  3. Addr::None => {
  4. n = Addr::Addr(Box::new(Node {
  5. value: val,
  6. left: Addr::None,
  7. right: Addr::None,
  8. }))
  9. }
  10. Addr::Addr(n) => Self::node_insert(n.left, val),
  11. }
  12. }

然而,编译器正确地发出警告:

  1. warning: value assigned to `n` is never read
  2. --> src/lib.rs:23:13
  3. |
  4. 23 | n = Addr::Addr(Box::new(Node {
  5. | ^
  6. |
  7. = help: maybe it is overwritten before being read?
  8. = note: `#[warn(unused_assignments)]` on by default

由于您拥有 n,您正在写入一个局部变量而不是树。相反,您应该获取 &mut Addr

  1. fn node_insert(n: &mut Addr<T>, val: T) {
  2. match n {
  3. Addr::None => {
  4. *n = Addr::Addr(Box::new(Node {
  5. value: val,
  6. left: Addr::None,
  7. right: Addr::None,
  8. }))
  9. }
  10. Addr::Addr(n) => Self::node_insert(&mut n.left, val),
  11. }
  12. }
英文:

Use pattern matching:

  1. fn node_insert(mut n: Addr&lt;T&gt;, val: T) {
  2. match n {
  3. Addr::None =&gt; {
  4. n = Addr::Addr(Box::new(Node {
  5. value: val,
  6. left: Addr::None,
  7. right: Addr::None,
  8. }))
  9. }
  10. Addr::Addr(n) =&gt; Self::node_insert(n.left, val),
  11. }
  12. }

However, the compiler rightfully warns:

  1. warning: value assigned to `n` is never read
  2. --&gt; src/lib.rs:23:13
  3. |
  4. 23 | n = Addr::Addr(Box::new(Node {
  5. | ^
  6. |
  7. = help: maybe it is overwritten before being read?
  8. = 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 &amp;mut Addr:

  1. fn node_insert(n: &amp;mut Addr&lt;T&gt;, val: T) {
  2. match n {
  3. Addr::None =&gt; {
  4. *n = Addr::Addr(Box::new(Node {
  5. value: val,
  6. left: Addr::None,
  7. right: Addr::None,
  8. }))
  9. }
  10. Addr::Addr(n) =&gt; Self::node_insert(&amp;mut n.left, val),
  11. }
  12. }

huangapple
  • 本文由 发表于 2023年2月26日 20:43:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/75572054.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定