Печать дерева - попытка доступа к полю, но поле с таким именем не найдено
Я пытаюсь написать свою первую программу на Rust. Я хочу напечатать простое дерево на экране, но не могу получить доступ к value
собственность, это говорит
Ошибка 1 при попытке доступа к полю
value
по типуNode
, но поле с таким именем не найдено 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; },
}
}
}
3 ответа
Просто потому что оба варианта Node
иметь value
поле, не означает, что вы можете получить к нему доступ напрямую. Вы можете получить его, сопоставив по значению (это эквивалентно):
let value = match leaf {
Node::Branch { value, .. } => value,
Node::Leaf { value } => value,
};
let value = match leaf {
Node::Branch { value, .. } | Node::Leaf { value } => value,
};
Но если вы собираетесь делать это много, вы, вероятно, захотите добавить метод:
impl Node {
pub fn get_value(&self) -> i32 {
match self {
&Node::Branch { value, .. } => value,
&Node::Leaf { value } => value,
}
}
}
... который вы затем можете использовать так:
let value = leaf.get_value();
Поскольку все ваши варианты перечисления имеют одно и то же поле, вы можете извлечь поле во внешнюю структуру и сохранить только те поля, которые различаются внутри перечисления. Таким образом, у вас есть прямой доступ к внутреннему value
поле. Когда вы хотите узнать, является ли ваш узел Branch
или Leaf
нужно совпадать на kind
поле. Также я предлагаю использовать Rc<Node>
вместо *const Node
как доступ к значению *const Node
указывает на необходимость небезопасного кода и, скорее всего, приведет к неприятностям в более сложном коде.
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) };
}
Я думаю, что вы действительно хотите, это следующий код: PlayPen
Используя мои магические способности интуиции, я предполагаю, что у вас есть такой код:
enum Node {
Branch { value: i32 },
Leaf { value: i32 },
}
fn main() {
let leaf = Node::Leaf { value: 15 };
println!("{}", leaf.value);
}
Который действительно имеет ошибку:
<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);
^~~~~~~~~~
Проблема в том, что тип leaf
является Node
, а также Node
имеет два варианта, Branch
или же Leaf
, Там нет типа с именем Node::Branch
или же Node::Leaf
, Вы должны соответствовать в перечислении, чтобы исчерпывающе обработать все случаи:
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),
}
}