我正在尝试打印一棵树(现在是 LinkedList
,但会修复):
use std::io;
use std::rc::Rc;
enum NodeKind {
Branch(Rc<Node>),
Leaf,
}
struct Node {
value: i32,
kind: NodeKind,
}
fn main() {
let leaf = Node { value: 10, kind: NodeKind::Leaf };
let branch = Node { value: 50, kind: NodeKind::Branch(Rc::new(leaf)) };
let root = Node { value: 100, kind: NodeKind::Branch(Rc::new(branch)) };
let mut current = root;
while true {
println!("{}", current.value);
match current.kind {
NodeKind::Branch(next) => {
current = *next;
}
NodeKind::Leaf => {
break;
}
}
}
let mut reader = io::stdin();
let buff = &mut String::new();
let read = reader.read_line(buff);
}
编译器说:
error[E0507]: cannot move out of borrowed content
--> src/main.rs:24:27
|
24 | current = *next;
| ^^^^^ cannot move out of borrowed content
我只读取值,不改变任何东西。我正在将一个值从一个引用分配给另一个值,试图取消对 Rc<T>
的引用值并将其存储在本地 mut
变量。
也许这样的事情可能会奏效:
while true {
println!("{}", current.value);
match ¤t.kind {
&NodeKind::Branch(next) => {
current = next;
}
&NodeKind::Leaf => {
break;
}
}
}
或者也许
let mut current = &Rc::new(root);
while true {
println!("{}", current.value);
match current.kind {
NodeKind::Branch(next) => {
current = &next;
}
NodeKind::Leaf => {
break;
}
}
}
但我得到了同样的错误加上'next' does not live long enough
最佳答案
这里不需要clone,完全可以用引用来做你想实现的:
use std::rc::Rc;
enum NodeKind {
Branch(Rc<Node>),
Leaf,
}
struct Node {
value: i32,
kind: NodeKind,
}
fn main() {
let leaf = Node { value: 10, kind: NodeKind::Leaf };
let branch = Node { value: 50, kind: NodeKind::Branch(Rc::new(leaf)) };
let root = Node { value: 100, kind: NodeKind::Branch(Rc::new(branch)) };
let mut current = &root;
loop {
println!("{}", current.value);
match current.kind {
NodeKind::Branch(ref next) => {
current = &**next;
}
NodeKind::Leaf => break,
}
}
}
您的代码唯一重要的变化是匹配中的模式是 ref next
和 current
类型为 &Node
.
ref
模式通过引用绑定(bind)它们的变量,即 next
类型为 &Rc<Node>
.获取&Node
从中,您需要取消引用它两次才能获得 Node
然后再次引用得到&Node
.由于 Deref 强制转换,也可以写成 current = &next
, 编译器将插入适当数量的 *
s 自动为您服务。
我也从while (true)
变了至 loop
因为它更加地道,并且有助于编译器推理您的代码。
所有树状结构的遍历在 Rust 中都是这样完成的。 ref
模式允许不移出变量,这在你只需要读取数据时是绝对必要的。您可以找到更多关于模式以及它们如何与所有权和借用交互的信息 here .
关于enums - 匹配枚举时无法移出借用的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30463490/