1

I'm am trying to write my first Rust program. I want to print a simple tree on the screen, but I cannot access a value property, it says

Error 1 attempted access of field value on type Node, but no field with that name was found c:\users\zhukovskiy\documents\visual studio 2013\Projects\rust_application1\rust_application1\src\main.rs 21 20 rust_application1

use std::io;

enum Node {
    Branch { value: i32, next: *const Node },
    Leaf { value: i32 }
}

fn main() {
    let leaf = Node::Leaf { value: 15 };
    let branch = Node::Branch { value: 10, next: &leaf };
    let root = Node::Branch { value: 50, next: &branch };

    let current = root;
    loop {
        match current {
            Node::Branch => { println!("{}", current.value); current = current.next; },
            Node::Leaf => { println!("{}", current.value); break; }, 
        }
    }
}
oli_obk
  • 28,729
  • 6
  • 82
  • 98
Alex Zhukovskiy
  • 9,565
  • 11
  • 75
  • 151
  • @Shepmaster yes, it works, but I cannot iterate through the tree. I edited to demonstrate an idea. It doesn't work but show what I'm trying to get. But I think ket's answer allows me to do it. – Alex Zhukovskiy May 20 '15 at 04:49
  • I don't think my answer answers your question anymore. It might be one thing you wanted or a solution to your problem. But the answer to your question is given by @DK. You should be matching on the enum contents, not just the names – oli_obk May 20 '15 at 07:24
  • 1
    @ker okay, I'l mark his answer, if you will. Anyawy, both answers was very useful. – Alex Zhukovskiy May 20 '15 at 10:55

3 Answers3

4

Just because both variants of Node have a value field, doesn't mean you can access it directly. You can get it by matching on the value (these are equivalent):

let value = match leaf {
    Node::Branch { value, .. } => value,
    Node::Leaf { value } => value,
};

let value = match leaf {
    Node::Branch { value, .. } | Node::Leaf { value } => value,
};

But if you're going to do this a lot, you probably want to add a method:

impl Node {
    pub fn get_value(&self) -> i32 {
        match self {
            &Node::Branch { value, .. } => value,
            &Node::Leaf { value } => value,
        }
    }
}

...which you can then use like so:

let value = leaf.get_value();
DK.
  • 55,277
  • 5
  • 189
  • 162
2

Since all your enum variants have the same field, you can extract the field into an outer struct and only keep the fields that differ inside the enum. This way you have direct access to the inner value field. When you want to find out whether your node is a Branch or a Leaf, you need to match on the kind field. Also I suggest to use an Rc<Node> instead of a *const Node, as accessing the value the *const Node points to requires unsafe code and will most likely get you into trouble in more complex code.

enum NodeKind {
    Branch(*const Node),
    Leaf,
}

use NodeKind::*;

struct Node {
    value: i32,
    kind: NodeKind,
}

fn main() {
    let leaf = Node{ value: 15, kind: Leaf };
    let branch = Node { value: 10, kind: Branch(&leaf) };
    let root = Node { value: 50, kind: Branch(&branch) };
}

I think what you actually want is the following code: PlayPen

oli_obk
  • 28,729
  • 6
  • 82
  • 98
1

Using my magic powers of intuition, I'm guessing you have some code like this:

enum Node {
    Branch { value: i32 },
    Leaf { value: i32 },
}

fn main() {
    let leaf = Node::Leaf { value: 15 };

    println!("{}", leaf.value);
}

Which indeed has the error:

<anon>:9:20: 9:30 error: attempted access of field `value` on type `Node`, but no field with that name was found
<anon>:9     println!("{}", leaf.value);
                            ^~~~~~~~~~

The problem is that the type of leaf is Node, and Node has two variants, Branch or Leaf. There is no type called Node::Branch or Node::Leaf. You need to match on the enumeration to exhaustively handle all the cases:

enum Node {
    Branch { value: i32 },
    Leaf { value: i32 },
}

fn main() {
    let leaf = Node::Leaf { value: 15 };

    match leaf {
        Node::Branch { value } => println!("Branch [{}]", value),
        Node::Leaf { value }   => println!("Leaf [{}]", value),
    }
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366